为啥我在这里看到“Access-Control-Allow-Origin 不允许来源”错误? [复制]
Posted
技术标签:
【中文标题】为啥我在这里看到“Access-Control-Allow-Origin 不允许来源”错误? [复制]【英文标题】:Why am I seeing an "origin is not allowed by Access-Control-Allow-Origin" error here? [duplicate]为什么我在这里看到“Access-Control-Allow-Origin 不允许来源”错误? [复制] 【发布时间】:2012-03-08 19:00:20 【问题描述】:我看到以下错误:
Origin http://localhost:8080 is not allowed by Access-Control-Allow-Origin
使用此代码:
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);
这是什么原因造成的,我该如何解决?
【问题讨论】:
您确定您使用的 youtube 入口点启用了 jsonp 吗?除非您使用服务器端代理或 jsonp 端点,否则您不能对外部域进行 ajax 调用。 【参考方案1】:这里,我们需要为 Apache Http 做两件事
1) 在 httpd.config 文件中,取消注释该文件
LoadModule headers_module modules/mod_headers.so
2) 在底部添加这一行。
Header set Access-Control-Allow-Origin "*"
【讨论】:
【参考方案2】:在当前域之外发出 ajax 请求时,javascript 会受到限制。
Ex 1:您的域是 example.com,您想向 test.com 发出请求 => 您不能。 示例 2:您的域是 example.com,您想向 inner.example.com 发出请求 => 您不能。 Ex 3:您的域是 example.com:80,您想向 example.com:81 发出请求 => 您不能 EX 4:您的域是 example.com,您想向 example.com 发出请求 => 可以。出于安全原因,Javascript 受到“同源策略”的限制,因此恶意脚本无法联系远程服务器并发送敏感数据。
jsonp 是使用 javascript 的另一种方式。您发出请求,结果被封装到在客户端运行的回调函数中。这与将新的脚本标记链接到 html 的头部部分相同(您知道您可以在此处从与您的域不同的域加载脚本)。 但是,要使用 jsonp,必须正确配置服务器。如果不是这种情况,则不能使用 jsonp,并且必须依赖服务器端代理(php、ASP 等)。有很多与这个主题相关的指南,只需谷歌它!
【讨论】:
谢谢!我不知道这会发生在同一主机但在不同的端口。 我可以使用 AmplifyJS 发送到不同的域吗? 我从来没有使用过 AmplifyJS,我不知道。如果它只是一个 Javascript 库(如 jQuery),我非常怀疑你是否可以避免使用 jsonp。如果它也有服务器部分,它仍然是可能的。我不能说更多,对不起。 jsonp 不是只对GET
请求有效吗?
在我的情况下,我试图连接到 EF 连接字符串中的不同数据库,导致 CORS 错误(ASP.NET Web API)【参考方案3】:
我在使用 ajax 访问 php 页面时遇到相同的错误消息(javascript 和 php 文件都位于同一服务器上)。
原因是我在 JavaScript 中将 IP 地址指定为域。这使浏览器认为对 php 文件的调用在另一台服务器上。
因此,摆脱此错误消息的简单解决方案。 a) 验证 javascript 和 php 文件在同一台服务器上 b) 确保您的 JavaScript(例如 http://www.smartana.co.uk/myJavaScript.js)ajax 中的 url(尤其是域)反映您的服务器 url(例如 http://www.smartana.co.uk/myServer.php)。
【讨论】:
【参考方案4】:如果您使用谷歌浏览器作为浏览器,您可以添加 CORS 扩展并激活它,它将解决漏洞问题,而无需更改代码中的任何内容
【讨论】:
【参考方案5】:由于“同源策略”,XMLHttpRequest 不会让您到达localhost:8080
。
您可以通过在localhost:8080
上的响应中添加标头来允许来自现代浏览器的请求:
Access-Control-Allow-Origin: *
您可以通过向 HTTP 服务器添加指令或通过服务器端代码(PHP、Ruby 等)添加标头来实现。
在 https://developer.mozilla.org/en/http_access_control 上阅读更多关于跨域 ajax 请求的信息
【讨论】:
如果我理解正确,那么 API 或远程资源的服务器(在本例中为 YouTube 服务器)必须设置标头,即必须设置此标头的是 API 托管商,而不是API 调用者。 还有其他人觉得这很混乱吗?使用 Fiddler,我可以看到正在发出请求并返回有效结果......然后我得到一个异常。所以服务器似乎根本不在乎。但是服务器是需要配置的吗? 这里服务器不关心。浏览器试图通过仅允许返回服务器允许列表中的请求来保护用户。 需要修改httpd.conf文件还是php.ini文件? @FedericoCapaldo 在这种情况下,您将创建自己的 API,充当代理,将请求转发到原始 API。【参考方案6】:如果您使用 apache,则可以:将其放入/在您的公共根目录中创建一个 .htaccess 文件,并添加您可能需要的任何其他文件扩展名。
<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>
【讨论】:
【参考方案7】:对于本地开发,您可以使用修改 HTTP 响应标头的工具。例如Charles 可以通过包含的重写工具做到这一点:Rewrite Tool
只需为目标域/位置添加新规则:
Type: Add Header
Where: Response
Replace
Name: Access-Control-Allow-Origin
Value: *
Replace All
【讨论】:
【参考方案8】:在您的解决方案中添加 global.asax。
添加
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
在
protected void Application_BeginRequest(object sender, EventArgs e)
【讨论】:
为什么人们不赞成这个?这是在 ASP.net 中实现此目的的一种方法 我试过这个,但没有奏效。仍然收到错误。使用 MVC5 添加“Application_BeginRequest”将允许对 API 的所有方法进行交叉调用。如果我想为单个网络方法做这件事怎么办?【参考方案9】:如果您来自 java 背景,一种可能的解决方案是制作一个 servlet,它为您的 javascript 调用 Web 服务。类似于 GET(Your-choice) 方法中的以下代码...
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 名称!
【讨论】:
【参考方案10】:如果您使用的是 Chrome,一个简单的解决方法(仅用于开发目的)是使用选项 --disable-web-security
。
【讨论】:
你肯定只想为开发目的而做,从不在冲浪时 同意@kynan 并更新了我的答案。 希望我今天早些时候知道这一点。对于生产部署,我们使用 nginx,因此最容易处理 CORS 标头,或者它们可能位于同一个域:端口上。它仅适用于我想绕过它的本地开发人员。 如何启用它? (如何倒退?)【参考方案11】:与此特定问题无关,但对于在这种情况下使用 jQuery 的任何人...如果您尝试使用 jQuery 发出 JSONP 请求并省略魔术回调参数,也会导致此错误:callback=?
【讨论】:
魔术参数也可以有其他名称。文档:api.jquery.com/jQuery.getJSON/#jsonp以上是关于为啥我在这里看到“Access-Control-Allow-Origin 不允许来源”错误? [复制]的主要内容,如果未能解决你的问题,请参考以下文章