Javascript XmlHttpRequest 错误:Access-Control-Allow-Origin 不允许 Origin null

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3595515/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 05:22:46  来源:igfitidea点击:

XmlHttpRequest error: Origin null is not allowed by Access-Control-Allow-Origin

javascriptjqueryxmlhttprequestcorsjsonp

提问by Drew Noakes

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

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

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

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

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.

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。

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?

如果我直接从浏览器查询该 URL,它工作正常。这是怎么回事,我能解决这个问题吗?我是否错误地编写了我的查询,或者这是 Panoramio 阻止我尝试做的事情?

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

Google 没有在错误消息中找到任何有用的匹配项。

EDIT

编辑

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);
  });
});

You can run the example online.

您可以在线运行该示例

EDIT 2

编辑 2

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

感谢 Darin 在这方面的帮助。 上面的代码是错误的。改用这个:

$().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...
  });
});

采纳答案by ssokolow

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

作为记录,据我所知,您有两个问题:

  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-Originheader came in.

  2. 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 Originheader. However, file://URLs produce a null Originwhich can't be authorized via echo-back.

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

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

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.

Darin 建议使用$.getJSON. 如果它看到callback=?URL 中的子字符串,将请求类型从默认的“json”更改为“jsonp”会有点神奇。

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

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

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

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

  1. If you're trying to use JSONP, make sure one of the following is the case:
    • You're using $.getand set dataTypeto jsonp.
    • You're using $.getJSONand included callback=?in the URL.
  2. If you're trying to do a cross-domain XMLHttpRequest via CORS...
    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)
  1. 如果您尝试使用 JSONP,请确保是以下情况之一:
    • 您正在使用$.get并设置dataTypejsonp.
    • 您正在使用$.getJSON并包含callback=?在 URL 中。
  2. 如果您尝试通过 CORS 执行跨域 XMLHttpRequest ...
    1. 确保您正在通过http://. 通过运行的脚本file://对 CORS 的支持有限。
    2. 确保浏览器确实支持 CORS。(Opera 和 Internet Explorer 迟到了)

回答by Thomas Decaux

You need to maybe add a HEADER in your called script, here is what I had to do in PHP:

您可能需要在被调用的脚本中添加一个 HEADER,这是我必须在 PHP 中执行的操作:

header('Access-Control-Allow-Origin: *');

More details in Cross domain AJAX ou services WEB(in French).

跨域 AJAX ou services WEB(法语)中的更多详细信息。

回答by CodeGroover

For a simple HTML project:

对于一个简单的 HTML 项目:

cd project
python -m SimpleHTTPServer 8000

Then browse your file.

然后浏览您的文件。

回答by Darin Dimitrov

Works for me on Google Chrome v5.0.375.127 (I get the alert):

适用于 Google Chrome v5.0.375.127(我收到警报):

$.get('http://www.panoramio.com/wapi/data/get_photos?v=1&key=dummykey&tag=test&offset=0&length=20&callback=?&minx=-30&miny=0&maxx=0&maxy=150',
function(json) {
    alert(json.photos[1].photoUrl);
});

Also I would recommend you using the $.getJSON()method instead as the previous doesn't work on IE8 (at least on my machine):

此外,我建议您改用该$.getJSON()方法,因为以前的方法不适用于 IE8(至少在我的机器上):

$.getJSON('http://www.panoramio.com/wapi/data/get_photos?v=1&key=dummykey&tag=test&offset=0&length=20&callback=?&minx=-30&miny=0&maxx=0&maxy=150', 
function(json) {
    alert(json.photos[1].photoUrl);
});

You may try it online from here.

您可以从这里在线试用。



UPDATE:

更新:

Now that you have shown your code I can see the problem with it. You are having both an anonymous function and inline function but both will be called processImages. That's how jQuery's JSONP support works. Notice how I am defining the callback=?so that you can use an anonymous function. You may read more about it in the documentation.

现在你已经展示了你的代码,我可以看到它的问题。您同时拥有匿名函数和内联函数,但两者都将被调用processImages。这就是 jQuery 的 JSONP 支持的工作原理。请注意我如何定义callback=?以便您可以使用匿名函数。您可以在文档中阅读更多相关信息

Another remark is that you shouldn't call eval. The parameter passed to your anonymous function will already be parsed into JSON by jQuery.

另一个注意事项是你不应该调用 eval。传递给匿名函数的参数已经被 jQuery 解析为 JSON。

回答by Cheng Chen

As long as the requested server supports the JSON data format, use the JSONP (JSON Padding) interface. It allows you to make external domain requests without proxy servers or fancy header stuff.

只要请求的服务器支持JSON数据格式,就使用JSONP(JSON Padding)接口。它允许您在没有代理服务器或花哨的标题内容的情况下发出外部域请求。

回答by Quentin

It's the same origin policy, you have to use a JSON-P interface or a proxy running on the same host.

这是同源策略,您必须使用 JSON-P 接口或在同一主机上运行的代理。

回答by romu31

We managed it via the http.conffile (edited and then restarted the HTTP service):

我们通过http.conf文件管理它(编辑然后重新启动 HTTP 服务):

<Directory "/home/the directory_where_your_serverside_pages_is">
    Header set Access-Control-Allow-Origin "*"
    AllowOverride all
    Order allow,deny
    Allow from all
</Directory>

In the Header set Access-Control-Allow-Origin "*", you can put a precise URL.

在 中Header set Access-Control-Allow-Origin "*",您可以放置​​一个精确的 URL。

回答by user2701060

If you are doing local testing or calling the file from something like file://then you need to disable browser security.

如果您正在进行本地测试或从类似的地方调用文件,file://那么您需要禁用浏览器安全性。

On MAC: open -a Google\ Chrome --args --disable-web-security

在 MAC 上: open -a Google\ Chrome --args --disable-web-security

回答by Kalpesh Patel

In my case, same code worked fine on Firefox, but not on Google Chrome. Google Chrome's JavaScript console said:

就我而言,相同的代码在 Firefox 上运行良好,但在 Google Chrome 上运行不正常。谷歌浏览器的 JavaScript 控制台说:

XMLHttpRequest cannot load http://www.xyz.com/getZipInfo.php?zip=11234. 
Origin http://xyz.com is not allowed by Access-Control-Allow-Origin.
Refused to get unsafe header "X-JSON"

I had to drop the www part of the Ajax URL for it to match correctly with the origin URL and it worked fine then.

我必须删除 Ajax URL 的 www 部分才能与原始 URL 正确匹配,然后它工作正常。

回答by mAsT3RpEE

Not all servers support jsonp. It requires the server to set the callback function in it's results. I use this to get json responses from sites that return pure json but don't support jsonp:

并非所有服务器都支持 jsonp。它要求服务器在其结果中设置回调函数。我使用它从返回纯 json 但不支持 jsonp 的站点获取 json 响应:

function AjaxFeed(){

    return $.ajax({
        url:            'http://somesite.com/somejsonfile.php',
        data:           {something: true},
        dataType:       'jsonp',

        /* Very important */
        contentType:    'application/json',
    });
}

function GetData() {
    AjaxFeed()

    /* Everything worked okay. Hooray */
    .done(function(data){
        return data;
    })

    /* Okay jQuery is stupid manually fix things */
    .fail(function(jqXHR) {

        /* Build HTML and update */
        var data = jQuery.parseJSON(jqXHR.responseText);

        return data;
    });
}