对于从文件://URL 运行的应用程序发出的请求,“Access-Control-Allow-Origin 不允许 Origin null"错误

2022-01-15 00:00:00 cors xmlhttprequest jquery javascript jsonp

我正在开发一个页面,该页面通过 jQuery 的 AJAX 支持从 Flickr 和 Panoramio 中提取图像.

I'm developing a page that pulls images from Flickr and Panoramio via jQuery's AJAX support.

Flickr 端工作正常,但是当我尝试从 Panoramio $.get(url, callback) 时,我在 Chrome 的控制台中看到一个错误:

The Flickr side is working fine, but when I try to $.get(url, callback) from Panoramio, I see an error in Chrome's console:

XMLHttpRequest 无法加载 http://www.panoramio.com/wapi/data/get_photos?v=1&key=dummykey&tag=test&offset=0&length=20&callback=processImages&minx=-30&miny=0&maxx=0&maxy=150.Access-Control-Allow-Origin 不允许 Origin null.

XMLHttpRequest cannot load http://www.panoramio.com/wapi/data/get_photos?v=1&key=dummykey&tag=test&offset=0&length=20&callback=processImages&minx=-30&miny=0&maxx=0&maxy=150. Origin null is not allowed by Access-Control-Allow-Origin.

如果我直接从浏览器查询该 URL,它可以正常工作.发生了什么事,我可以解决这个问题吗?我是否错误地编写了我的查询,或者这是否是 Panoramio 阻碍我尝试做的事情?

If I query that URL from a browser directly it works fine. What is going on, and can I get around this? Am I composing my query incorrectly, or is this something that Panoramio does to hinder what I'm trying to do?

Google 没有在 错误信息.

Google didn't turn up any useful matches on the error message.

编辑

这里有一些显示问题的示例代码:

Here's some sample code that shows the problem:

$().ready(function () {
  var url = 'http://www.panoramio.com/wapi/data/get_photos?v=1&key=dummykey&tag=test&offset=0&length=20&callback=processImages&minx=-30&miny=0&maxx=0&maxy=150';

  $.get(url, function (jsonp) {
    var processImages = function (data) {
      alert('ok');
    };

    eval(jsonp);
  });
});

您可以在线运行示例.

编辑 2

感谢达林在这方面的帮助.上面的代码是错误的.改用这个:

Thanks to Darin for his help with this. THE ABOVE CODE IS WRONG. Use this instead:

$().ready(function () {
  var url = 'http://www.panoramio.com/wapi/data/get_photos?v=1&key=dummykey&tag=test&offset=0&length=20&minx=-30&miny=0&maxx=0&maxy=150&callback=?';

  $.get(url, function (data) {
    // can use 'data' in here...
  });
});

推荐答案

作为记录,据我所知,您遇到了两个问题:

For the record, as far as I can tell, you had two problems:

  1. 您没有将jsonp"类型说明符传递给您的$.get,因此它使用的是普通的XMLHttpRequest.但是,您的浏览器支持 CORS(跨域资源共享)以允许跨域 XMLHttpRequest(如果服务器确定).这就是 Access-Control-Allow-Origin 标头出现的地方.

  1. You weren't passing a "jsonp" type specifier to your $.get, so it was using an ordinary XMLHttpRequest. However, your browser supported CORS (Cross-Origin Resource Sharing) to allow cross-domain XMLHttpRequest if the server OKed it. That's where the Access-Control-Allow-Origin header came in.

我相信您提到过您是从 file://URL 运行它的.CORS 标头有两种方式表明跨域 XHR 正常.一个是发送 Access-Control-Allow-Origin: * (如果你是通过 $.get 访问 Flickr,他们一定是这样做的),而另一个是回显 Origin 标头的内容.但是,file:// URL 会产生一个空的 Origin,无法通过回显授权.

I believe you mentioned you were running it from a file:// URL. There are two ways for CORS headers to signal that a cross-domain XHR is OK. One is to send Access-Control-Allow-Origin: * (which, if you were reaching Flickr via $.get, they must have been doing) while the other was to echo back the contents of the Origin header. However, file:// URLs produce a null Origin which can't be authorized via echo-back.

Darin 建议使用 $.getJSON 以迂回的方式解决了第一个问题.如果它在 URL 中看到子字符串 callback=?,将请求类型从其默认的json"更改为jsonp"会有点神奇.

The first was solved in a roundabout way by Darin's suggestion to use $.getJSON. It does a little magic to change the request type from its default of "json" to "jsonp" if it sees the substring callback=? in the URL.

解决了第二个问题,不再尝试从 file:// URL 执行 CORS 请求.

That solved the second by no longer trying to perform a CORS request from a file:// URL.

为了向其他人澄清,以下是简单的故障排除说明:

To clarify for other people, here are the simple troubleshooting instructions:

  1. 如果您尝试使用 JSONP,请确保满足以下条件之一:
    • 您正在使用 $.get 并设置 dataTypejsonp.
    • 您正在使用 $.getJSON 并在 URL 中包含 callback=?.
  1. If you're trying to use JSONP, make sure one of the following is the case:
    • You're using $.get and set dataType to jsonp.
    • You're using $.getJSON and included callback=? in the URL.
  1. 确保您通过 http:// 进行测试.通过 file:// 运行的脚本对 CORS 的支持有限.
  2. 确保浏览器确实支持CORS.(Opera 和 Internet Explorer 迟到了)
  1. Make sure you're testing via http://. Scripts running via file:// have limited support for CORS.
  2. Make sure the browser actually supports CORS. (Opera and Internet Explorer are late to the party)

相关文章