问题描述
我正在研究我的这个个人项目只是为了好玩,我想读取一个位于 http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml 并解析 xml 并使用它来转换货币之间的值.
I am working on this personal project of mine just for fun where I want to read an xml file which is located at http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml and parse the xml and use it to convert values between the currencies.
到目前为止,我已经想出了下面的代码,这是为了读取 XML 非常基本的代码,但是我收到了以下错误.
So far I have come up with the code below which is pretty basic in order to read the XML but I get the following error.
XMLHttpRequest 无法加载 ****.没有访问控制允许来源"请求的资源上存在标头.起源'http://run.jsbin.com' 因此不允许访问.
XMLHttpRequest cannot load ****. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://run.jsbin.com' is therefore not allowed access.
$(document).ready(
function() {
$.ajax({
type: 'GET',
url: 'http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml',
dataType: 'xml',
success: function(xml){
alert('aaa');
}
});
}
);
我没有发现我的代码有任何问题,所以我希望有人能指出我的代码有什么问题以及如何修复它.
I don't see anything wrong with my code so I am hoping someone could point out what I am doing wrong with my code and how I could fix it.
推荐答案
您将无法对 http://www.ecb.europa.eu/stats/eurofxref/eurofxref- 进行 ajax 调用由于 http://run.jsbin.com
的文件中的 daily.xmlorigin_policy" rel="noreferrer">同源策略.
You won't be able to make an ajax call to http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml
from a file deployed at http://run.jsbin.com
due to the same-origin policy.
由于源(又名 origin)页面和 target URL 位于不同的域(run.jsbin.com
和 www.ecb.europa.eu
),您的代码实际上是在尝试制作 跨域(CORS)请求,不是普通的GET
.
As the source (aka origin) page and the target URL are at different domains (run.jsbin.com
and www.ecb.europa.eu
), your code is actually attempting to make a Cross-domain (CORS) request, not an ordinary GET
.
简而言之,同源策略表示浏览器应该只允许对 HTML 页面的同一域中的服务进行 ajax 调用.
In a few words, the same-origin policy says that browsers should only allow ajax calls to services at the same domain of the HTML page.
http://www.example.com/myPage.html
的页面只能直接请求 http://www.example.com
的服务,例如 http://www.example.com/api/myService
.如果服务托管在另一个域(例如 http://www.ok.com/api/myService
),浏览器将不会直接调用(如您所料).相反,它将尝试发出 CORS 请求.
A page at http://www.example.com/myPage.html
can only directly request services that are at http://www.example.com
, like http://www.example.com/api/myService
. If the service is hosted at another domain (say http://www.ok.com/api/myService
), the browser won't make the call directly (as you'd expect). Instead, it will try to make a CORS request.
简而言之,要跨不同域执行 (CORS) 请求*,您的浏览器:
To put it shortly, to perform a (CORS) request* across different domains, your browser:
- 将在原始请求中包含
Origin
标头(以页面的域为值)并照常执行;然后 - 仅当服务器响应该请求包含 足够的标题(
Access-Control-Allow-Origin
是 其中一个) 允许 CORS 请求,浏览将完成调用(几乎**与 HTML 页面在同一个域中的方式完全相同).- 如果没有出现预期的标头,浏览器就会放弃(就像它对您所做的那样).
- Will include an
Origin
header in the original request (with the page's domain as value) and perform it as usual; and then - Only if the server response to that request contains the adequate headers (
Access-Control-Allow-Origin
is one of them) allowing the CORS request, the browse will complete the call (almost** exactly the way it would if the HTML page was at the same domain).- If the expected headers don't come, the browser simply gives up (like it did to you).
* 上面描述了简单请求中的步骤,例如没有花哨的标头的常规GET
.如果请求不简单(如POST
以application/json
作为内容类型),浏览器将等待它片刻,并在完成之前先发送对目标 URL 的OPTIONS
请求.像上面一样,只有当对这个OPTIONS
请求的响应包含 CORS 标头时,它才会继续.此OPTIONS
调用称为 preflight 请求.
** 我说几乎是因为常规调用和 CORS 调用之间还有其他区别.一个重要的问题是,即使响应中存在某些标头,也不会如果它们未包含在Access-Control-Expose-Headers
标头中,则由浏览器拾取.
* The above depicts the steps in a simple request, such as a regularGET
with no fancy headers. If the request is not simple (like aPOST
withapplication/json
as content type), the browser will hold it a moment, and, before fulfilling it, will first send anOPTIONS
request to the target URL. Like above, it only will continue if the response to thisOPTIONS
request contains the CORS headers. ThisOPTIONS
call is known as preflight request.
** I'm saying almost because there are other differences between regular calls and CORS calls. An important one is that some headers, even if present in the response, will not be picked up by the browser if they aren't included in theAccess-Control-Expose-Headers
header.只是一个错字吗? 有时 JavaScript 代码在目标域中只是一个错字.你检查过吗?如果页面位于
www.example.com
,它只会定期调用www.example.com
!其他 URL,例如api.example.com
甚至example.com
或www.example.com:8080
被视为 不同 域由浏览器!是的,如果端口不同,那就是不同的域!Was it just a typo? Sometimes the JavaScript code has just a typo in the target domain. Have you checked? If the page is at
www.example.com
it will only make regular calls towww.example.com
! Other URLs, such asapi.example.com
or evenexample.com
orwww.example.com:8080
are considered different domains by the browser! Yes, if the port is different, then it is a different domain!添加标头.启用 CORS 的最简单方法是添加必要的标头(如
Access-Control-Allow-Origin
)到服务器的响应.(每种服务器/语言都有办法做到这一点 - 在此处查看一些解决方案.)Add the headers. The simplest way to enable CORS is by adding the necessary headers (as
Access-Control-Allow-Origin
) to the server's responses. (Each server/language has a way to do that - check some solutions here.)不得已:如果您没有服务器端访问该服务的权限,您也可以镜像它(通过反向代理等工具),并包括那里所有必要的标题.
Last resort: If you don't have server-side access to the service, you can also mirror it (through tools such as reverse proxies), and include all the necessary headers there.
这篇关于jQuery XML 错误“请求的资源上不存在‘Access-Control-Allow-Origin’标头."的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!