Hi! I've encountered an issue while developing a plugin. The fetch
function works perfectly on PC, but on the mobile app, it encounters cross-origin (CORS) problems. Is there a way to resolve this? Or should I wait for the next mobile version update to see if the cross-origin restrictions will be lifted?
Looking forward to your advice!
Do you have some code to share?
Yes, and the code is very simple:
response = await fetch(apiUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${apiKey}`,
},
body: JSON.stringify(requestBody),
});
On PC it works very well.
On mobile app, if CORS not set allowed by server side, response will be "undefined".
By default, when using Flask (python) for server testing on my local machine, the plugin on mobile application is unable to perform fetch requests even within a local network.
However, after enabling Cross-Origin Resource Sharing (CORS) with flask_cors, the same plugin on mobile app functions correctly.
Therefore, it can be concluded that the issue was indeed due to CORS restrictions.
That makes sense, thanks for the update. My guess is that in mobile we're using the fetch
from a web view, while on desktop it might be the one from Node.js, so that's why the one on mobile is restricted although it probably shouldn't be.
Maybe we need to setup the webview to ignore CORS. @personalizedrefriger might know more since he implemented plugin support on mobile.
2 Likes
I think the simplest solution would be to add a fetch
method to Joplin's plugin API (e.g. something similar to this draft implementation).
Background: Plugin architecture on mobile
On mobile, plugins run within iframe
s inside a background WebView
:
On web, the background WebView
is also an iframe
. Part of the goal of this design was to reduce memory usage — if I recall correctly, having one WebView
per plugin led to higher memory usage than a single WebView
with multiple plugin iframes
.
As a result, CORS restrictions could be a result of restrictions on the parent WebView
, or restrictions on the iframe
s within the WebView
.
React Native WebView CORS
There are several stale closed issues in the React Native WebView repository related to CORS restrictions: Intercept response headers to bypass CORs · Issue #1781 · react-native-webview/react-native-webview · GitHub, Any hack/option to bypass CORS? · Issue #2155 · react-native-webview/react-native-webview · GitHub, Allow CORS · Issue #570 · react-native-webview/react-native-webview · GitHub
Based on this, I suspect that the CORS issue (at least on iOS/Android) is a limitation of react-native-webview
.
1 Like
Hmm ok that's a pity we can't remove this restriction within a webview but if it's a known issue there's probably not much we can do here.
Adding our own implementation is likely to be difficult too, isn't it?
I think this depends on how complete the fetch
API should be. If it only supports returning text/JSON, it might be sufficient to wrap shim.fetch
in a new class (similar to the existing APIs in plugins/api
).