question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

XHR Request fail with CORS Access-Control-Allow-Origin on Cordova android 10

See original GitHub issue

Bug Report

Problem

Simple GET xhr request (https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests) in cordova-android@^10.0.0 trigger CORS

What is expected to happen?

Simple xhr GET request should not trigger CORS

What does actually happen?

Simple xhr GET request should trigger CORS

Example: Access to XMLHttpRequest at ‘https://www.google.com/’ from origin ‘https://localhost’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

Information

I have tested with two Cordova applications out of the box :

  • The first one in Cordova 9.1 works fine the GET xhr call retrieve the remote site content XHR request save as CURL from Chrome network

curl ‘https://www.google.com/
-H ‘authority: www.google.com’
-H ‘user-agent: Mozilla/5.0 (Linux; Android 11; SM-G991B Build/RP1A.200720.012; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/93.0.4577.82 Mobile Safari/537.36’
-H ‘accept: /
-H ‘x-requested-with: com.example.hellocdv9’
-H ‘sec-fetch-site: cross-site’
-H ‘sec-fetch-mode: cors’
-H ‘sec-fetch-dest: empty’
-H ‘accept-language: fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7’
-H ‘cookie: CONSENT=PENDING+960’
–compressed

Result in Chrome console :

The XMLHttpRequest in status 200 with Google.com site content

  • The second one in Cordova 10.1.1 does not work and is blocked by CORS XHR request save as CURL from Chrome network

curl ‘https://www.google.com/
-H ‘authority: www.google.com’
-H ‘user-agent: Mozilla/5.0 (Linux; Android 11; SM-G991B Build/RP1A.200720.012; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/93.0.4577.82 Mobile Safari/537.36’
-H ‘accept: /
-H ‘origin: https://localhost
-H ‘x-requested-with: com.example.hellocdv10’
-H ‘sec-fetch-site: cross-site’
-H ‘sec-fetch-mode: cors’
-H ‘sec-fetch-dest: empty’
-H ‘referer: https://localhost/
-H ‘accept-language: fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7’
–compressed

Result in Chrome console :

The XMLHttpRequest in status 0 with the following error Access to XMLHttpRequest at ‘https://www.google.com/’ from origin ‘https://localhost’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

Command or Code

I’ve created two Cordova applications

  • Cordova 9.x

cordova create hellocdv9 com.example.hellocdv9 HelloWorldcdv9 cd hellocdv9/ cordova platform add android cordova build android adb install ./platforms/android/app/build/outputs/apk/debug/app-debug.apk

  • Cordova 10.x

cordova create hellocdv10 com.example.hellocdv10 HelloWorldcdv10 cd hellocdv10/ cordova platform add android@^10.0.0 cordova plugin remove cordova-plugin-whitelist cordova build android adb install ./platforms/android/app/build/outputs/apk/debug/app-debug.apk

  • File changes for both applications

www/index.html

32c32
<         <meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *; img-src 'self' data: content:;">
---
>         <meta http-equiv="Content-Security-Policy" content="default-src * data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *; img-src 'self' data: content:;">

www/js/index.js

28a29,37
>     let xhr = new XMLHttpRequest();
>     xhr.open('GET', 'https://www.google.com');
>     xhr.onload = function() {
>         console.log(xhr, xhr.responseText);
>     };
>     xhr.onerror = function(e) {
>         console.error(e, xhr);
>     };
>     xhr.send();

Environment, Platform, Device

Device

android: 11 target api: 30

Version information

First app

cordova: 9.1.0 cordova-plugin-whitelist: 1.3.5

Second App

cordova: 10.1.1 No plugin

Cordova Cli: 10.0.0

Checklist

  • I searched for existing GitHub issues
  • I updated all Cordova tooling to most recent version
  • I included all the necessary information above

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:2
  • Comments:12 (4 by maintainers)

github_iconTop GitHub Comments

17reactions
breautekcommented, Sep 17, 2021

Some background knowledge…

Content-Security-Policy is a different security mechanism than CORS (Cross-Origin Resource Sharing).

In cordova-android@10, we implemented something called a WebAssetLoader, which proxies requests through https://localhost protocol. The WebAssetLoader kind of acts like a private web server only accessible to your app. This was done because some web view features requires you to be on a “secure context” (e.g https) for the features to be enabled. In doing so, it does enable the CORS enforcement.

Cordova android 9.x uses the plain old file system (file://) which didn’t enforced CORs. This is why you see the XHR request work in 9.x, but not in 10.x. You can make 10.x behave like 9.x by enabling the AndroidInsecureFileModeEnabled preference:

<preference name="AndroidInsecureFileModeEnabled" value="true" />

But let’s assume you don’t want to use this workaround

CORS is a security mechanism for CORS-enabled browsers that are controlled by the backend server. So in this case, https://google.com must provide the required response headers for the browser to accept the request response. They do not provide the Access-Control-Allow-Origin: https://localhost or Access-Control-Allow-Origin: * response header, therefore the request is rejected by the browser / webview.

There is no API available in the webview to disable CORS. Assuming you don’t have access to https://google.com to make the appropriate backend change, the only workaround at this point is to not use the browser’s request mechanism (neither fetch() or XMLHttpRequest) and instead find/build a cordova plugin that does a native request, which is not bounded by CORS.

Another approach is to configure a proxy server that is configured to use the CORS protocol in which your app can make request to, which will be redirected to https://google.com, then you can relay the response back to the client. This approach will still allow you to use the browser’s HTTP request APIs.

Now that we got all that information out there… May I ask more details on your use case?

3reactions
Ahmed-Abdelftahcommented, Jun 9, 2022

Some background knowledge…

Content-Security-Policy is a different security mechanism than CORS (Cross-Origin Resource Sharing).

In cordova-android@10, we implemented something called a WebAssetLoader, which proxies requests through https://localhost protocol. The WebAssetLoader kind of acts like a private web server only accessible to your app. This was done because some web view features requires you to be on a “secure context” (e.g https) for the features to be enabled. In doing so, it does enable the CORS enforcement.

Cordova android 9.x uses the plain old file system (file://) which didn’t enforced CORs. This is why you see the XHR request work in 9.x, but not in 10.x. You can make 10.x behave like 9.x by enabling the AndroidInsecureFileModeEnabled preference:

<preference name="AndroidInsecureFileModeEnabled" value="true" />

But let’s assume you don’t want to use this workaround

CORS is a security mechanism for CORS-enabled browsers that are controlled by the backend server. So in this case, https://google.com must provide the required response headers for the browser to accept the request response. They do not provide the Access-Control-Allow-Origin: https://localhost or Access-Control-Allow-Origin: * response header, therefore the request is rejected by the browser / webview.

There is no API available in the webview to disable CORS. Assuming you don’t have access to https://google.com to make the appropriate backend change, the only workaround at this point is to not use the browser’s request mechanism (neither fetch() or XMLHttpRequest) and instead find/build a cordova plugin that does a native request, which is not bounded by CORS.

Another approach is to configure a proxy server that is configured to use the CORS protocol in which your app can make request to, which will be redirected to https://google.com, then you can relay the response back to the client. This approach will still allow you to use the browser’s HTTP request APIs.

Now that we got all that information out there… May I ask more details on your use case?

This maybe the most detailed answer I have ever read , thank you!

Read more comments on GitHub >

github_iconTop Results From Across the Web

CORS + Cordova : issues with : Access-Control-Allow-Origin
It doesn't work for me when I run as browser. I still have: "Cross-Origin Request Blocked: The Same Origin Policy disallows reading the...
Read more >
CORS issue when testing on Android - Auth0 Community
stack: "Error: Request has been terminated Possible causes: the network is offline, Origin is not allowed by Access-Control-Allow-Origin, ...
Read more >
[GitHub] [cordova-android] breautek commented on issue #1354
[GitHub] [cordova-android] breautek commented on issue #1354: XHR Request fail with CORS Access-Control-Allow-Origin on Cordova android 10.
Read more >
CORS Errors: Cross-Origin Resource Sharing - Ionic Framework
CORS errors happen in web apps if requests are made and servers don't return required headers. Read about Cross-Origin Resource Sharing in Ionic ......
Read more >
Cordova Android 10.1.1 Released!
Access to XMLHttpRequest at 'https://externalURL' from origin 'https://localhost' has been blocked by CORS policy: Request header field pragma ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found