Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CORS error for application running from file:// scheme

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. 
like image 361
KevInSol Avatar asked Sep 18 '14 13:09

KevInSol


People also ask

How do you fix a CORS violation error?

In order to fix CORS, you need to make sure that the API is sending proper headers (Access-Control-Allow-*). That's why it's not something you can fix in the UI, and that's why it only causes an issue in the browser and not via curl: because it's the browser that checks and eventually blocks the calls.

How do I fix cross-origin requests are only supported for protocol schemes?

Just change the url to http://localhost instead of localhost . If you open the html file from local, you should create a local server to serve that html file, the simplest way is using Web Server for Chrome . That will fix the issue.

What is CORS and how do you fix it?

It's a mechanism that restricts requests coming from a different origin (domain). A request coming from a different origin is known as a cross-origin request. Cross-origin requests are vital for when your site needs to load data from other services. CORS allows servers to specify who can access their resources and how.

What is the meaning of CORS error?

The CORS behavior, commonly termed as CORS error, is a mechanism to restrict users from accessing shared resources. This is not an error but a security measure to secure users or the website which you are accessing from a potential security bleach.


1 Answers

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:

  • CORS and phonegap apps
  • Domain whitelisting in Apache Cordova - a security model that controls access to outside domains.

Check these resources for more info on CORS:

  • Cross-Origin resource sharing and file://
  • A nice CORS tutorial: http://www.html5rocks.com/en/tutorials/cors/
  • Working around origin policy
  • HTTP access control (CORS) (Mozilla)

Check also Browser support for CORS:

  • http://caniuse.com/#feat=cors

And for the record formal CORS specification on W3C :)

like image 144
Blaise Avatar answered Oct 19 '22 12:10

Blaise