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

Flickr 端工作正常,但是当我尝试 $.get(url, callback) 从 Panoramio,我在 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 所做的事情来阻碍我想做的事情吗?

谷歌没有找到任何有用的匹配 错误信息.

编辑

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

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

感谢达林对此的帮助。 上面的代码是错误的。 使用这个代替:

$().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...
  });
});
有帮助吗?

解决方案

据我所知,您有两个问题:

  1. 您不会将“ JSONP”类型的指定符传递给您的 $.get, ,因此它使用了普通的xmlhttprequest。但是,您的浏览器支持CORS(交叉原始资源共享),以允许跨域XMLHTTPREQUEST,如果服务器也可以。那就是 Access-Control-Allow-Origin 标头进来。

  2. 我相信您提到您正在从文件中运行它:// url。 CORS标头有两种方法可以发出交叉域XHR的信号。一个是发送 Access-Control-Allow-Origin: * (如果您要到达Flickr, $.get, ,他们一定是在做),而另一个是回荡的 Origin 标题。然而, file:// URL产生无效 Origin 无法通过回声授权。

第一个是通过Darin的建议以回旋的方式解决的 $.getJSON. 。如果看到substring,将请求类型从其默认的“ JSON”更改为“ JSONP”有点魔术 callback=? 在URL中。

这解决了第二个,不再试图从一个 file:// URL。

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

  1. 如果您想使用JSONP,请确保以下是这样的之一:
    • 您正在使用 $.get 并设置 dataTypejsonp.
    • 您正在使用 $.getJSON 并包括 callback=? 在URL中。
  2. 如果您想通过CORS进行跨域XMLHTTPRequest ...
    1. 确保您正在通过 http://. 。通过运行的脚本 file:// 对CORS的支持有限。
    2. 确保浏览器 实际上支持CORS. 。 (歌剧和Internet Explorer对聚会很晚)

其他提示

您可能需要在您所谓的脚本中添加标头,这是我在PHP中必须要做的:

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

更多详细信息 跨域Ajax OU服务网络 (用法语)。

对于一个简单的HTML项目:

cd project
python -m SimpleHTTPServer 8000

然后浏览您的文件。

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

你可以尝试 从这里在线.


更新:

现在您已经显示了您的代码,我可以看到它的问题。您既具有匿名函数又有内联函数,但两者都会被调用 processImages. 。这就是JQUERY的JSONP支持的工作方式。注意我如何定义 callback=? 这样您就可以使用匿名函数。您可以阅读更多 文档中关于它.

另一个说明是您不应该致电评估。传递给您的匿名函数的参数将已经由JQuery解析为JSON。

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

是的 相同的原点政策, ,您必须使用在同一主机上运行的JSON-P接口或代理。

我们通过以下方式管理它 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。

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

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

就我而言,相同的代码在Firefox上效果很好,但在Google Chrome上不行。 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正确匹配,然后运行良好。

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

我使用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/

最后,将代理-URL传递给您的脚本。

作为最终注意 Mozilla文档明确说

如果将标题授予通配符为: 访问控制 - 允许孔: *。 由于访问控制 - 允许原素明确提到 http://foo..example,凭证认知内容将返回到调用Web内容。

结果,不仅是使用'*'的不良做法。根本不起作用:)

我在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]

确保您使用的是最新版本的jQuery。我们面临着jQuery 1.10.2的错误,使用JQuery 1.11.1后解决了错误。

伙计们,

我遇到了类似的问题。但是使用提琴手,我能够解决这个问题。问题在于,在Web API端的CORS实现中配置的客户端URL不得具有后挡率。通过Google Chrome提交请求并检查 TextView 标签 标题 提琴手的部分,错误消息指出了这样的内容:

*“指定的策略原点your_client_url:/'是无效的。 它不能以前锋的斜线结束。”

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

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

谢谢,安迪

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

所以搜索一点,我发现 这个 使用:

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

然后它将在 http://localhost:8000.

对于PHP-我在Chrome,Safari和Firefox上的这项工作

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

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

使用file://使用Axios呼叫PHP实时服务

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top