提问人:Bazinga777 提问时间:11/7/2013 最后编辑:SyscallBazinga777 更新时间:4/17/2021 访问量:282379
jQuery XML 错误“请求的资源上不存在”Access-Control-Allow-Origin“标头。
jQuery XML error ' No 'Access-Control-Allow-Origin' header is present on the requested resource.'
问:
我正在做我的这个个人项目只是为了好玩,我想读取位于 http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml 的 xml 文件并解析 xml 并使用它来转换货币之间的值。
到目前为止,我已经想出了下面的代码,这是非常基本的代码,以便读取XML,但是我收到以下错误。
XMLHttpRequest 无法加载 ****。没有“访问控制允许源” 标头存在于请求的资源上。起源 因此,“http://run.jsbin.com”是不允许访问的。
$(document).ready(
function() {
$.ajax({
type: 'GET',
url: 'http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml',
dataType: 'xml',
success: function(xml){
alert('aaa');
}
});
}
);
我看不出我的代码有什么问题,所以我希望有人能指出我的代码出了什么问题以及如何修复它。
答:
由于同源策略,您将无法从部署在http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml
http://run.jsbin.com
由于源(又名源)页面和目标 URL 位于不同的域 ( 和 ),因此您的代码实际上是在尝试发出跨域 (CORS) 请求,而不是普通的 .run.jsbin.com
www.ecb.europa.eu
GET
简而言之,同源策略表示,浏览器应该只允许对 HTML 页面同一域中的服务进行 ajax 调用。
例:
一个页面只能直接请求位于 的服务,比如 。如果服务托管在另一个域(例如),浏览器不会直接进行调用(如您所料)。相反,它将尝试发出 CORS 请求。http://www.example.com/myPage.html
http://www.example.com
http://www.example.com/api/myService
http://www.ok.com/api/myService
简而言之,要跨不同域执行 (CORS) 请求*,您的浏览器:
- 将在原始请求中包含一个标头(以页面的域为值)并照常执行;然后
Origin
- 只有当服务器对该请求的响应包含允许 CORS 请求的足够标头(
Access-Control-Allow-Origin
就是其中之一)时,浏览才会完成调用(几乎与 HTML 页面位于同一域时完全相同)。- 如果预期的标头没有出现,浏览器就会放弃(就像它对你所做的那样)。
* 以上描述了一个简单的请求中的步骤,例如没有花哨标头的常规 GET
。如果请求不简单(例如以 application/json
为内容类型的 POST
),浏览器将保留它片刻,并且在完成它之前,将首先向目标 URL 发送 OPTIONS
请求。如上所述,仅当对此 OPTIONS
请求的响应包含 CORS 标头时,它才会继续。此 OPTIONS
调用称为预检请求。
** 我之所以这么说,几乎是因为常规呼叫和 CORS 呼叫之间还有其他区别。一个重要的问题是,如果某些标头未包含在 Access-Control-Expose-Headers
标头中,即使它们存在于响应中,浏览器也不会选取它们。
如何解决?
这只是一个错别字吗?有时,JavaScript 代码在目标域中只有一个拼写错误。你检查过了吗?如果该页面位于该页面,它只会定期调用!其他 URL,例如 or 甚至 or 被浏览器视为不同的域!是的,如果端口不同,那么它就是不同的域!www.example.com
www.example.com
api.example.com
example.com
www.example.com:8080
添加标头。启用 CORS 的最简单方法是将必要的标头 (as ) 添加到服务器的响应中。(每个服务器/语言都有一种方法可以做到这一点 - 在此处查看一些解决方案。Access-Control-Allow-Origin
不得已而为之:如果您没有对服务的服务器端访问权限,您还可以镜像它(通过反向代理等工具),并在其中包含所有必要的标头。
评论
Access-Control-Allow-Origin
Access-Control-Allow-Origin
如果您在服务器上启用了 php,则有一种黑客方法可以做到这一点。更改此行:
url: 'http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml',
到这一行:
url: '/path/to/phpscript.php',
然后在 PHP 脚本中(如果您有权使用 file_get_contents() 函数):
<?php
header('Content-type: application/xml');
echo file_get_contents("http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml");
?>
Php 似乎并不介意该 url 是否来自不同的来源。就像我说的,这是一个骇人听闻的答案,我确信它有问题,但它对我有用。
编辑: 如果你想在 php 中缓存结果,这里是你将使用的 php 文件:
<?php
$cacheName = 'somefile.xml.cache';
// generate the cache version if it doesn't exist or it's too old!
$ageInSeconds = 3600; // one hour
if(!file_exists($cacheName) || filemtime($cacheName) > time() + $ageInSeconds) {
$contents = file_get_contents('http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml');
file_put_contents($cacheName, $contents);
}
$xml = simplexml_load_file($cacheName);
header('Content-type: application/xml');
echo $xml;
?>
缓存代码从这里获取。
评论
file_get_contents
上一个:如何使用 vba 解析 XML
评论