19

I have an AngularJS/Cordova app which polls a JSON service on a remote server:

$http({method: 'GET', url: 'http://example.com/index.php'})

Developing in the browser and running off my intranet apache server (http://dev) I get "No 'Access-Control-Allow-Origin' header is present" so I fix this by adding:

Header set Access-Control-Allow-Origin "http://dev"

All works fine, and I see Origin:http://dev in my Chrome dev tools.

So, having to think about this for the first time, I wonder what the Origin will be when the app runs in the Android/iOS webviews. I decide to do a build and deploy on my devices and expect to see the same error in remote debugging (Safari for iOS and Weinre for Android), but to my surprise it works (without sending any CORS headers)! I also find that in both devices the app runs in the webview under the file:// scheme, rather than (what I assumed) a http server of some sorts provided by the phone OS.

So research seems to suggest that CORS is not required for file:// - such a "site' may access any XHR resource on any domain. But, when I test this on desktop browsers I find that while Safari does not need CORS for file:// but Chrome does, and FireFox works either way without CORS

So my questions:

1) why is my app working without CORS in Android/iOS - is it because CORS does not apply to file://, or, is Cordova doing something to make it work in the device?

I have <access origin="*"/> in my config

2) if, pending answers to Q1, I should want to be on the safe site and explicitly allow requests from apps, what value do you give Access-Control-Allow-Origin for file:// "hosts"? in my debugging there is no Origin header in the requests from file://

3) in addition to blocking the XHR request to the remote server, Chrome is also blocking my app templates (I'm using separate files), see below. Is this a potential issue with my app, or just a Chrome issue that I do not need to worry about?

XMLHttpRequest cannot load file:///Volumes/projects/phonegap/www/templates/tabs.html. Cross origin requests are only supported for HTTP. 
sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
KevInSol
  • 2,560
  • 4
  • 32
  • 46

1 Answers1

27

There are two ways for CORS headers to signal that a cross-domain XHR should be allowed:

  • sending Access-Control-Allow-Origin: * (allow all hosts)
  • put the host you would like to allow into the Origin header by your backend

As for the file:// URLs they will produce a null Origin which can't be authorized via the second option (echo-back).

As mentioned:

Cross-domain policy does not apply to PhoneGap (for a variety of reasons, basically because your app is essentially running off the file:// URI on-device).

Please be aware that you will have to set up a whitelist for your apps to access these external domains.

As for the Chrome problem, which can be seen in the developer's console:

Failed to load resource: net::ERR_FILE_NOT_FOUND file:///C:/2.html XMLHttpRequest cannot load file:///C:/2.html. Received an invalid response. Origin 'null' is therefore not allowed access.

there was a discussion on Chromium project's issue tracker, #40787. They mark the issues as won't fix as that behaviour is happening by design.

There is a workaround proposed to simply switch off CORS in Chrome for development purposes, starting chrome with --allow-file-access-from-files --disable-web-security

e.g. for Windows

`C:\Users\YOUR_USER\AppData\Local\Google\Chrome\Application\chrome.exe --allow-file-access-from-files --disable-web-security`

Here is some more cordova related answer:

Check these resources for more info on CORS:

Check also Browser support for CORS:

And for the record formal CORS specification on W3C :)

Community
  • 1
  • 1
Blaise
  • 7,230
  • 6
  • 43
  • 53
  • thanks for your response. I did actually see most of the links you posted. As per my Q3, Chrome is blocking both my remote server and the local requests for templates, can I ignore this and just work with Safari? – KevInSol Sep 22 '14 at 14:33
  • 1
    @KevInSol I would ignore Chrome and go work with Safari or Firefox for local development. Please check my last update on the answer - I included a link to a discussion from Chromium developers that mark that issue as won't fix for them. – Blaise Sep 23 '14 at 10:23
  • Thank you Blaise, I've actually been using Safari the past few days for its ease of remote debugging on iOS. I see that link you poosted is pretty old, but I guess the situation remains the same. Thanks for your help! – KevInSol Sep 25 '14 at 16:41
  • 2
    I'm having the opposite problem -- my Cordova app insists on sending `Origin: file://` instead of `null origin` as this answer suggests it will (and should) do. Obviously the server (correctly) rejects this origin. See for example: https://github.com/playframework/playframework/issues/5193. Whitelisting does not help. – Raman Sep 27 '16 at 00:11
  • Hey @Raman I have the exact same issue! Check http://stackoverflow.com/questions/39720465/cordova-cors-ios. – mitsest Sep 27 '16 at 09:18