Javascript CORS、Cordova、AngularJs $http 和 file:// 混淆
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25914071/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
CORS, Cordova, AngularJs $http and file:// confusion
提问by KevInSol
I have an AngularJS/Cordova app which polls a JSON service on a remote server:
我有一个 AngularJS/Cordova 应用程序,它轮询远程服务器上的 JSON 服务:
$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:
在浏览器中开发并运行我的 Intranet apache 服务器 ( http://dev) 我得到“没有‘Access-Control-Allow-Origin’标头存在”所以我通过添加来解决这个问题:
Header set Access-Control-Allow-Origin "http://dev"
All works fine, and I see Origin:http://devin my Chrome dev tools.
一切正常,我Origin:http://dev在 Chrome 开发工具中看到。
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.
所以,不得不第一次考虑这个问题,我想知道当应用程序在 Android/iOS webviews 中运行时,Origin 会是什么。我决定在我的设备上进行构建和部署,并希望在远程调试中看到相同的错误(iOS 的 Safari 和 Android 的 Weinre),但令我惊讶的是它有效(不发送任何 CORS 标头)!我还发现,在这两种设备中,应用程序都在 file:// 方案下的 webview 中运行,而不是(我假设的)手机操作系统提供的某种 http 服务器。
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
所以研究似乎表明 file:// 不需要 CORS——这样的“站点”可以访问任何域上的任何 XHR 资源。但是,当我在桌面浏览器上测试时,我发现虽然 Safari 不需要 CORS 文件:// 但 Chrome 可以,FireFox 可以在没有 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?
1) 为什么我的应用程序在 Android/iOS 中没有 CORS 的情况下工作 - 是因为 CORS 不适用于 file://,还是 Cordova 正在做一些事情使其在设备中工作?
I have <access origin="*"/>in my config
我<access origin="*"/>在我的配置
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://
2) 如果在对 Q1 的回答未决时,我应该在安全站点上并明确允许来自应用程序的请求,那么您为 file://“hosts”赋予 Access-Control-Allow-Origin 什么值?在我的调试中,来自 file:// 的请求中没有 Origin 标头
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?
3) 除了阻止对远程服务器的 XHR 请求之外,Chrome 还阻止了我的应用程序模板(我使用的是单独的文件),见下文。这是我的应用程序的潜在问题,还是我不需要担心的 Chrome 问题?
XMLHttpRequest cannot load file:///Volumes/projects/phonegap/www/templates/tabs.html. Cross origin requests are only supported for HTTP.
回答by Blaise
There are two ways for CORS headers to signal that a cross-domain XHR should be allowed:
CORS 标头有两种方式来表示应该允许跨域 XHR:
- sending
Access-Control-Allow-Origin: *(allow all hosts) - put the host you would like to allow into the
Originheader by your backend
- 发送
Access-Control-Allow-Origin: *(允许所有主机) - 将您希望允许的主机放入
Origin后端的标头中
As for the file://URLs they will produce a nullOriginwhich can't be authorized via the second option (echo-back).
至于file://URL,它们将产生一个无法通过第二个选项 ( echo-back)授权的null。Origin
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.
跨域策略不适用于 PhoneGap(出于多种原因,基本上是因为您的应用程序本质上是在设备上运行 file:// URI)。
请注意,您必须为应用程序设置白名单才能访问这些外部域。
As for the Chromeproblem, which can be seen in the developer's console:
至于Chrome的问题,可以在开发者控制台看到:
Failed to load resource: net::ERR_FILE_NOT_FOUND file:///C:/2.htmlXMLHttpRequest cannot load file:///C:/2.html. Received an invalid response. Origin 'null' is therefore not allowed access.
Failed to load resource: net::ERR_FILE_NOT_FOUND file:///C:/2.htmlXMLHttpRequest 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 fixas that behaviour is happening by design.
有一个关于Chromium 项目的问题跟踪器的讨论,#40787。他们将问题标记为无法解决,因为该行为是设计使然。
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
有一个解决方法建议简单地关闭 Chrome 中的 CORS 以用于开发目的,从 chrome 开始 --allow-file-access-from-files --disable-web-security
e.g. for Windows
例如对于 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:
这是更多与cordova相关的答案:
- CORS and phonegap apps
- Domain whitelisting in Apache Cordova- a security model that controls access to outside domains.
- CORS 和 phonegap 应用程序
- Apache Cordova 中的域白名单- 一种控制对外部域访问的安全模型。
Check these resources for more info on CORS:
查看这些资源以获取有关 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)
- 跨域资源共享和file://
- 一个不错的 CORS 教程:http://www.html5rocks.com/en/tutorials/cors/
- 解决原始策略
- HTTP 访问控制 (CORS) (Mozilla)
Check also Browser support for CORS:
还检查浏览器对 CORS 的支持:
And for the record formal CORS specification on W3C:)
并在 W3C 上记录正式的 CORS 规范:)

