Why am I seeing an “origin is not allowed by Access-Control-Allow-Origin” error here?
我看到以下错误:
1 | Origin http://localhost:8080 is not allowed by Access-Control-Allow-Origin |
使用此代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | var http = new getXMLHttpRequestObject(); var url ="http://gdata.youtube.com/action/GetUploadToken"; var sendXML = '<?xml version="1.0"?><entry xmlns="http://www.w3.org/2005/Atom"'+ 'xmlns:media="http://search.yahoo.com/mrss/'+ 'xmlns:yt="http://gdata.youtube.com/schemas/2007">'+ '<media:group><media:title type="plain">My First API</media:title>'+ '<media:description type="plain">First API</media:description>'+ '<media:category scheme="http://gdata.youtube.com/schemas/2007/categories.cat">People</media:category>'+ '<media:keywords>first, api</media:keywords></media:group></entry>'; http.open("POST", url, true); http.setRequestHeader("Authorization","AuthSub token=" + AccessToken); http.setRequestHeader("X-GData-Key","key="+ dev_key); http.setRequestHeader("Content-Type","application/atom+xml; charset=UTF-8"); http.onreadystatechange = function() { if(http.readyState == 4) { alert(http.responseXML); } } http.send(sendXML); |
是什么导致这种情况,我该如何解决?
在当前域之外发出ajax请求时,Javascript受到限制。
- 例1:你的域名是example.com,你想向test.com发出请求=>你不能。
- 例2:您的域名是example.com,您想向inner.example.com发送请求=>您不能。
- 例3:你的域名是example.com:80,你想向example.com发送请求:81 =>你不能
- EX 4:你的域名是example.com,你想向example.com发送请求=>你可以。
出于安全原因,Javascript受"同源策略"的限制,因此恶意脚本无法联系远程服务器并发送敏感数据。
jsonp是一种使用javascript的不同方式。您发出请求并将结果封装到在客户端中运行的回调函数中。它与将新脚本标记链接到html的head部分相同(您知道可以从不同的域加载脚本而不是您的脚本)。
但是,要使用jsonp,必须正确配置服务器。如果不是这种情况你不能使用jsonp,你必须依赖服务器端代理(PHP,ASP等)。有很多与此主题相关的指南,只是谷歌吧!
由于"相同的原始策略",XMLHttpRequest不允许您到达
您可以通过在
1 | Access-Control-Allow-Origin: * |
您可以通过向HTTP服务器添加指令或通过服务器端代码(PHP,Ruby,...)添加标头来实现。
在https://developer.mozilla.org/en/http_access_control上阅读有关Cross-Origin ajax请求的更多信息
如果您使用的是Chrome,那么一个简单的解决方法(仅用于开发目的)就是使用选项
在解决方案中添加global.asax。
加
1 | HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin","*"); |
在
1 2 3 | protected void Application_BeginRequest(object sender, EventArgs e) { } |
如果您使用apache,则可以正常工作:将其放入/创建公共根目录中的.htaccess文件,并添加您可能需要的任何其他文件扩展名。
1 2 3 4 5 | <FilesMatch"\.(ttf|otf|eot|woff|jpg|png|jpeg|gif|js|json|html|css)$"> <IfModule mod_headers.c> Header set Access-Control-Allow-Origin"*" </IfModule> </FilesMatch> |
对于本地开发,您可以使用工具来修改HTTP响应头。例如,Charles可以通过包含的重写工具来执行此操作:重写工具
只需为目标域/位置添加新规则:
1 2 3 4 5 6 | Type: Add Header Where: Response Replace Name: Access-Control-Allow-Origin Value: * Replace All |
在这里,我们需要为Apache Http做两件事
1)在httpd.config文件中,取消注释该文件
1 | LoadModule headers_module modules/mod_headers.so |
2)在底部添加此行。
1 | Header set Access-Control-Allow-Origin"*" |
如果您使用谷歌浏览器作为浏览器,您可以添加CORS扩展,并激活它,它将解决漏洞问题,而无需更改代码中的任何内容
如果你来自java背景,一个可能的解决方案是创建一个servlet,它为你的javascript调用Web服务。像GET(你选择)方法中的下面代码...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | JsonElement jelement; JsonArray jarray; try { URL url = new URL("http://rest."YOUR URL"#ba0482"); URLConnection connection = url.openConnection(); connection.setDoInput(true); InputStream inStream = connection.getInputStream(); BufferedReader input = new BufferedReader(new InputStreamReader(inStream)); jelement = new JsonParser().parse(input); jarray = jelement.getAsJsonArray(); response.setContentType("application/json"); PrintWriter out = response.getWriter(); out.print(jarray); out.flush(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } |
现在在javascript中只需将url指定为servlet名称!!
与此特定问题无关,但对于使用jQuery的情况下的任何人...如果您尝试使用jQuery创建JSONP请求并省略魔术回调参数,则也会导致此错误:
当使用ajax访问php页面时,我遇到了相同的错误消息(javascript和php文件都位于同一台服务器上)。
原因是我在我的JavaScript中将IP地址指定为域。这使浏览器相信对php文件的调用是在另一台服务器上。
所以一个简单的解决方案摆脱这个错误信息。
a)验证javascript和php文件在同一台服务器上
b)确保JavaScript中的URL(特别是域名)(例如http://www.smartana.co.uk/myJavaScript.js)ajax反映了您的服务器URL(例如http://www.smartana.co。英国/ myServer.php)。