Javascript AJAX 请求获取“请求的资源上不存在‘Access-Control-Allow-Origin’标头”错误
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/35304817/
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
AJAX request gets "No 'Access-Control-Allow-Origin' header is present on the requested resource" error
提问by Zoltán Schmidt
I attempt to send a GET
request in a jQuery AJAX request.
我尝试GET
在 jQuery AJAX 请求中发送请求。
$.ajax({
type: 'GET',
url: /* <the link as string> */,
dataType: 'text/html',
success: function() { alert("Success"); },
error: function() { alert("Error"); },
});
However, whatever I've tried, I got XMLHttpRequest cannot load <page>. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:7776' is therefore not allowed access.
但是,无论我尝试过什么,我都得到了 XMLHttpRequest cannot load <page>. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:7776' is therefore not allowed access.
I tried everything, from adding header : {}
definitions to the AJAX request to setting dataType
to JSONP
, or even text/plain
, using simple AJAX instead of jQuery, even downloading a plugin that enables CORS - but nothing could help.
我尝试了所有方法,从向header : {}
AJAX 请求添加定义到设置dataType
为JSONP
,甚至text/plain
使用简单的 AJAX 而不是 jQuery,甚至下载了启用 CORS 的插件 - 但没有任何帮助。
And the same happens if I attempt to reach any other sites.
如果我尝试访问任何其他站点,也会发生同样的情况。
Any ideas for a proper and simple solution? Is there any at all?
任何关于适当和简单解决方案的想法?有吗?
采纳答案by Chris Middleton
This is by design. You can't make an arbitrary HTTP request to another server using XMLHttpRequest unless that server allows it by putting out an Access-Control-Allow-Origin header for the requesting host.
这是设计使然。您不能使用 XMLHttpRequest 向另一台服务器发出任意 HTTP 请求,除非该服务器通过为请求主机发出 Access-Control-Allow-Origin 标头来允许它。
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
You could retrieve it in a script tag (there isn't the same restriction on scripts and images and stylesheets), but unless the content returned is a script, it won't do you much good.
您可以在脚本标记中检索它(对脚本、图像和样式表没有相同的限制),但除非返回的内容是脚本,否则它不会对您有多大好处。
Here's a tutorial on CORS:
这是关于 CORS 的教程:
This is all done to protect the end user. Assuming that an image is actually an image, a stylesheet is just a stylesheet and a script is just a script, requesting those resources from another server can't really do any harm.
这一切都是为了保护最终用户。假设一个图像实际上是一个图像,样式表只是一个样式表而脚本只是一个脚本,从另一个服务器请求这些资源不会真正造成任何伤害。
But in general, cross-origin requests can do really bad things. Say that you, Zoltan, are using coolsharks.com. Say also that you are logged into mybank.com and there is a cookie for mybank.com in your browser. Now, suppose that coolsharks.com sends an AJAX request to mybank.com, asking to transfer all your money into another account. Because you have a mybank.com cookie stored, they successfully complete the request. And all of this happens without your knowledge, because no page reload occurred. This is the danger of allowing general cross-site AJAX requests.
但总的来说,跨域请求会做一些非常糟糕的事情。假设您,Zoltan,正在使用coolsharks.com。还假设您已登录 mybank.com,并且您的浏览器中有 mybank.com 的 cookie。现在,假设coolsharks.com 向mybank.com 发送AJAX 请求,要求将您的所有资金转入另一个帐户。因为您存储了 mybank.com cookie,所以他们成功完成了请求。所有这一切都在您不知情的情况下发生,因为没有发生页面重新加载。这是允许一般跨站点 AJAX 请求的危险。
If you want to perform cross-site requests, you have two options:
如果要执行跨站点请求,有两种选择:
- Get the server you are making the request to to either
a. Admit you by putting out a Access-Control-Allow-Origin header that includes you (or *)
b. Provide you with a JSONP API.
- 获取您要向其发出请求的服务器
。通过放出包含您(或 *)的 Access-Control-Allow-Origin 标头来承认您
b. 为您提供 JSONP API。
or
或者
- Write your own browser that doesn't follow the standards and has no restrictions.
- 编写自己的浏览器,不遵循标准,没有限制。
In (1), you must have the cooperation of the server you are making requests to, and in (2), you must have control over the end user's browser. If you can't fulfill (1) or (2), you're pretty much out of luck.
在 (1) 中,您必须与您向其发出请求的服务器合作,在 (2) 中,您必须控制最终用户的浏览器。如果你不能满足 (1) 或 (2),那你就很不走运了。
However, there is a third option (pointed out by charlietfl). You can make the request from a server that you do control and then pass the result back to your page. E.g.
但是,还有第三种选择(由 charlietfl 指出)。您可以从您控制的服务器发出请求,然后将结果传回您的页面。例如
<script>
$.ajax({
type: 'GET',
url: '/proxyAjax.php?url=http%3A%2F%2Fstackoverflow.com%2F10m',
dataType: 'text/html',
success: function() { alert("Success"); },
error: function() { alert("Error"); }
});
</script>
And then on your server, at its most simple:
然后在您的服务器上,最简单的是:
<?php
// proxyAjax.php
// ... validation of params
// and checking of url against whitelist would happen here ...
// assume that $url now contains "http://stackoverflow.com/10m"
echo file_get_contents($url);
Of course, this method may run into other issues:
当然,这种方法可能会遇到其他问题:
- Does the site you are a proxy for require the correct referrer or a certain IP address?
- Do cookies need to be passed through to the target server?
- Does your whitelist sufficiently protect you from making arbitrary requests?
- Which headers (e.g. modify time, etc) will you be passing back to the browser as your server received them and which ones will you omit or change?
- Will your server be implicated as having made a request that was unlawful (since you are acting as a proxy)?
- 您作为代理的站点是否需要正确的引荐来源网址或特定的 IP 地址?
- cookie 是否需要传递到目标服务器?
- 您的白名单是否足以保护您免于提出任意请求?
- 当您的服务器收到它们时,您将哪些标头(例如修改时间等)传回浏览器,哪些将省略或更改?
- 您的服务器是否会因发出非法请求而受到牵连(因为您是代理)?
I'm sure there are others. But if none of those issues prevent it, this third method could work quite well.
我确定还有其他人。但如果这些问题都没有阻止它,这第三种方法可能会很好地工作。
回答by john Smith
you can ask the developers of that domain if they would set the appropriate header for you, this restriction is only for javascript, basically you can request the ressource from your server with php or whatever and the javascript requests the data from your domain then
您可以询问该域的开发人员是否会为您设置适当的标头,此限制仅适用于 javascript,基本上您可以使用 php 或其他方式从您的服务器请求资源,然后 javascript 从您的域请求数据
回答by Joel Wigton
Old question, but I'm not seeing this solution, which worked for me, anywhere. So hoping this can be helpful for someone.
老问题,但我没有看到这个解决方案,它在任何地方都对我有用。所以希望这对某人有帮助。
First, remember that it makes no sense to try modifying the headers of the requestto get around a cross-origin resource request. If that were all it took, it would be easy for malicious users to then circumvent this security measure.
首先,请记住,尝试修改请求的标头来绕过跨域资源请求是没有意义的。如果仅此而已,恶意用户就很容易绕过此安全措施。
Cross-origin requests in this context are only possible if the partner site's server allows it through their responseheaders.
仅当合作伙伴站点的服务器通过其响应标头允许它时,此上下文中的跨源请求才可能发生。
I got this to work in Django without any CORS middleware by setting the following headers on the response:
通过在响应中设置以下标头,我让它在没有任何 CORS 中间件的 Django 中工作:
response["Access-Control-Allow-Origin"] = "requesting_site.com"
response["Access-Control-Allow-Methods"] = "GET"
response["Access-Control-Allow-Headers"] = "requesting_site.com"
Most answers on here seem to mention the first one, but not the second two. I've just confirmed they are all required. You'll want to modify as needed for your framework or request method (GET, POST, OPTION).
这里的大多数答案似乎都提到了第一个,但没有提到第二个。我刚刚确认它们都是必需的。您需要根据您的框架或请求方法(GET、POST、OPTION)的需要进行修改。
p.s. You can try "*"
instead of "requesting_site.com"
for initial development just to get it working, but it would be a security hole to allow everysite access. Once working, you can restrict it for your requesting site only to make sure you don't have any formatting typos.
ps 您可以尝试"*"
代替"requesting_site.com"
初始开发来使其正常工作,但这将是一个允许每个站点访问的安全漏洞。工作后,您可以将其限制为仅用于请求站点,以确保您没有任何格式错别字。