ChatGPT解决这个技术问题 Extra ChatGPT

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

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

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

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。

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

Google 没有在 error message 上找到任何有用的匹配项。

编辑

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

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

您可以run the example online

编辑 2

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

$().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...
  });
});
您发出请求来自的 URL 是什么样的?例如,这不会是您 document.write 进入的动态生成的 iframe
您能否将请求的 HTTP 响应发布到每个服务。我敢打赌 Panoramio 没有提供 Access-Control-Allow-Origin。有关示例,请参见 w3.org/TR/cors
@Kevin,如果服务器发送 JSONP,则不需要这些标头。
@Pekka,我目前正在本地机器上运行该页面(file:///C:/)。不涉及iframe
@drew 如果您从 http URL 运行它会发生什么?它不应该以这种方式产生影响,而只是为了排除这种可能性。

s
ssokolow

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

您没有将“jsonp”类型说明符传递给您的 $.get,因此它使用的是普通的 XMLHttpRequest。但是,您的浏览器支持 CORS(跨域资源共享)以允许跨域 XMLHttpRequest(如果服务器确定)。这就是 Access-Control-Allow-Origin 标头出现的地方。我相信您提到您是从 file:// URL 运行它的。 CORS 标头有两种方式表明跨域 XHR 正常。一种是发送 Access-Control-Allow-Origin: * (如果您是通过 $.get 访问 Flickr,他们一定是这样做的),另一种是回显 Origin 标头的内容。但是,file:// URL 会产生一个空的 Origin,无法通过回显授权。

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

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

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

如果您尝试使用 JSONP,请确保满足以下条件之一:您正在使用 $.get 并将 dataType 设置为 jsonp。您正在使用 $.getJSON 并包含 callback=?在网址中。如果您尝试通过 CORS 执行跨域 XMLHttpRequest... 请确保您通过 http:// 进行测试。通过 file:// 运行的脚本对 CORS 的支持有限。确保浏览器确实支持 CORS。 (Opera 和 Internet Explorer 迟到了)


那么解决这个问题的方法是什么?
如果使用参数 --allow-file-access-from-files 启动,某些浏览器(如 chrome)允许 CORS
callback=? 对我不起作用,但 jsonp=? 对我有用。对此有何解释?
@crunkchitis:我不确定为什么 callback=? 不适合你,因为当前的 jQuery 文档仍然说它应该,但是,如果我正确阅读它们,他们也说 anything_else=? 也可以工作。
P
Peter Mortensen

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

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

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


P
Peter Mortensen

对于一个简单的 HTML 项目:

cd project
python -m SimpleHTTPServer 8000

然后浏览您的文件。


D
Darin Dimitrov

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

另外我建议您使用 $.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);
});

你可以试试online from here

更新:

现在您已经显示了您的代码,我可以看到它的问题。您同时拥有匿名函数和内联函数,但两者都将被称为 processImages。这就是 jQuery 的 JSONP 支持的工作原理。请注意我如何定义 callback=? 以便您可以使用匿名函数。您可以阅读更多about it in the documentation

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


我得到 Uncaught TypeError: $.get is not a function at :1:3
A
Ahmad Awais

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


Q
Quentin

它是 same origin policy,您必须使用 JSON-P 接口或在同一主机上运行的代理。


D
DontVoteMeDown

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

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


P
Peter Mortensen

我们通过 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>

Header set Access-Control-Allow-Origin "*" 中,您可以输入一个精确的 URL。


这不适用于 XAMPP 的 Apache。问题依然存在。
这是不安全的。看这里为什么; stackoverflow.com/questions/7564832/…
正如@RobQuist 所说,这是不安全的。
P
Peter Mortensen

就我而言,相同的代码在 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"

我不得不删除 Ajax URL 的 www 部分,以便它与原始 URL 正确匹配,然后它工作得很好。


u
user2688838

最后请注意,Mozilla documentation explicitly says

如果标头通配符为:Access-Control-Allow-Origin: *,上述示例将失败。由于 Access-Control-Allow-Origin 明确提及 http://foo.example,因此将凭证认知内容返回给调用 Web 内容。

因此,使用“*”不仅仅是一种不好的做法。根本行不通:)


A
Ahmad Awais

并非所有服务器都支持 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;
    });
}

i
imilbaev

我使用 Apache 服务器,所以我使用了 mod_proxy 模块。启用模块:

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so

然后加:

ProxyPass /your-proxy-url/ http://service-url:serviceport/

最后,将 proxy-url 传递给您的脚本。


T
Tyler

对于 PHP - 在 Chrome、safari 和 firefox 上为我工作

https://w3c.github.io/webappsec-cors-for-developers/#avoid-returning-access-control-allow-origin-null

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

使用 axios 通过 file:// 调用 php 实时服务


这也适用于我,注意 null 是一个字符串而不是实际的 NULL。我将它用作header('Access-Control-Allow-Origin: '.( trim($_SERVER['HTTP_REFERER'],'/') ?:'null'),true);,它也允许从远程服务器到另一个服务器的交叉源,并且本地文件的 (string) null。
m
mslembro

我在 Chrome 中也遇到了同样的错误(我没有测试其他浏览器)。这是因为我在 domain.com 而不是 www.domain.com 上导航。有点奇怪,但我可以通过将以下行添加到 .htaccess 来解决问题。它将 domain.com 重定向到 www.domain.com 并解决了问题。我是一个懒惰的网络访问者,所以我几乎从不输入 www,但显然在某些情况下它是必需的。

RewriteEngine on
RewriteCond %{HTTP_HOST} ^domain\.com$ [NC]
RewriteRule ^(.*)$ http://www.domain.com/$1 [R=301,L]

G
Ganesh Kamath - 'Code Frenzy'

确保您使用的是最新版本的 JQuery。我们在 JQuery 1.10.2 中遇到了这个错误,并且在使用 JQuery 1.11.1 后该错误得到了解决


a
andymenon

伙计们,

我遇到了类似的问题。但是使用 Fiddler,我能够解决这个问题。问题是在 Web API 端的 CORS 实现中配置的客户端 URL 不能有尾部正斜杠。通过 Google Chrome 提交请求并检查 Fiddler 的 Headers 部分的 TextView 选项卡后,错误消息如下所示:

*“指定的策略来源 your_client_url:/' 无效。它不能以正斜杠结尾。”

这真的很古怪,因为它在 Internet Explorer 上运行没有任何问题,但在使用 Google Chrome 进行测试时让我很头疼。

我删除了 CORS 代码中的正斜杠并重新编译了 Web API,现在可以通过 Chrome 和 Internet Explorer 访问 API,没有任何问题。请试一试。

谢谢,安迪


M
MiJyn

by CodeGroover above 发布的解决方案中有一个小问题,如果您更改文件,则必须重新启动服务器才能实际使用更新的文件(至少在我的情况下)。

所以搜索了一下,我发现 this one 使用:

sudo npm -g install simple-http-server # to install
nserver # to use

然后它将在 http://localhost:8000 投放。