Fetch CORS Issue on Mobile End - Seeking Solution

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 iframes 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 iframes 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).