capacitor
capacitor copied to clipboard
bug: Capacitor Http and Native Bridge don't handle ReadableStream
Bug Report
Capacitor Version
npx cap doctor
[warn] The bundledWebRuntime configuration option has been deprecated. Can be safely deleted.
💊 Capacitor Doctor 💊
Latest Dependencies:
@capacitor/cli: 5.5.1
@capacitor/core: 5.5.1
@capacitor/android: 5.5.1
@capacitor/ios: 5.5.1
Installed Dependencies:
@capacitor/android: not installed
@capacitor/cli: 5.5.1
@capacitor/core: 5.5.1
@capacitor/ios: 5.5.1
[success] iOS looking great! 👌
Platform(s)
iOS (only tested)
Current Behavior
calling fetch('url', { method: 'POST', body: new URLSearchParams([ ['foo', 1], ['bar', true] ])
results in https://github.com/ionic-team/capacitor/blob/main/core/native-bridge.ts#L475 Request
being made with a body of ReadableStream
which is passed through convertBody
https://github.com/ionic-team/capacitor/blob/main/core/native-bridge.ts#L54
onto cap.nativePromise
which fails with a DataCloneError: The object can not be cloned.
in postToNative
Expected Behavior
you can call fetch
with the first parameter being a string url and the body being in the second parameter
Code Reproduction
Other Technical Details
npm --version
output: 9.8.1
node --version
output: 18.18.0
pod --version
output (iOS issues only): 1.10.1
Additional Context
Investigating and debugging more:
https://github.com/ionic-team/capacitor/blob/main/core/native-bridge.ts#L57
This doesn't seem to work, I had planned to expand it to cover URLSearchParams
but the body
property of the Request
object is a ReadableStream
so not sure how instanceof
would ever work...
Here's a sample:
https://codesandbox.io/s/capacitor-fetch-instanceof-testing-98cmm6?file=/src/index.ts
You will notice a JSON (string) request and a URLSearchParams request both log out as intanceof
Object
and ReadableStream
NOT the original types...
This code surely doesn't work? My next step is to build a full Capacitor example. Maybe there's something specific to iOS and Android devices that makes body of not type ReadableStream
?
I'm having a similar issue but it seems like it goes a bit deeper. I've been testing my app on my Android 12 phone (APK 31) with Chrome web view version 117 and when I tried to test it in an "old" Samsung S8+ with Android 9 (APK 28) and Chrome WebView version 97.0.4692.70 by login into my app, the request went off with an undefined
body. Digging through the issue I found that the Request API body as a ReadableStream is only available in Chrome from version 105 & what I think is the main issue for me, the fact that when the new Request()
constructor is called (either in RTK Query in my case, or called again in the fetch patch in capacitor) the request's body ends up undefined. If I disable CapacitorHttp in the config, the RTK query cloned request works as expected, so I'm suspecting the issue might be in the patched fetch in the native bridge code.
Android 12 (APK 31) Chrome WebView 117:
Samsung S8+ with Android 9 (APK 28) and Chrome WebView version 97.0.4692.70:
*Edit: Seems like I was wrong and jumped the gun, I changed the form request to use fetch instead of the rtk query mutation and the new Request()
in the native bridge didn't alter the request body. Looks like the issue might be some other place.
I'm getting the same issue trying to get the oidc-client-ts
OAuth flow from a Web App working in Android. The /token
endpoint creates a URLSearchParams
object and passes it to the body, which winds up empty after sending it across the bridge.
I can go into more detail but since the PR that solves this issue has already been approved I figure there's no need. Is there something else stopping this PR from being merged?
This issue has been labeled as type: bug
. This label is added to issues that that have been reproduced and are being tracked in our internal issue tracker.
Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Capacitor, please create a new issue and ensure the template is fully filled out.