Javascript “;访问控制允许原点”;不允许原点为空;从文件://URL运行的应用程序发出请求时出错

Javascript “;访问控制允许原点”;不允许原点为空;从文件://URL运行的应用程序发出请求时出错,javascript,jquery,xmlhttprequest,cors,jsonp,Javascript,Jquery,Xmlhttprequest,Cors,Jsonp,我正在开发一个页面,通过jQuery的AJAX支持从Flickr和Panoramio中提取图像 Flickr端工作正常,但当我尝试从Panoramio获取(url,回调)时,我在Chrome的控制台中看到一个错误: 无法加载XMLHttpRequest。访问控制允许原点不允许原点为null 如果我直接从浏览器中查询该URL,它可以正常工作。发生了什么事,我能绕开这件事吗?我是否编写了错误的查询,或者这是Panoramio为了阻止我的尝试而做的事情 谷歌没有在网上找到任何有用的匹配项 编辑 下面是

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

Flickr端工作正常,但当我尝试从Panoramio获取(url,回调)时,我在Chrome的控制台中看到一个错误:

无法加载XMLHttpRequest。访问控制允许原点不允许原点为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...
  });
});

在Google Chrome v5.0.375.127上对我有效(我收到警报):

另外,我建议您改用该方法,因为前面的方法在IE8上不起作用(至少在我的机器上不起作用):

你可以试试


更新:

现在,您已经展示了代码,我可以看到它的问题。您同时拥有匿名函数和内联函数,但这两个函数都将被调用
processImages
。jQuery的JSONP支持就是这样工作的。注意我是如何定义回调=?的,这样您就可以使用匿名函数了。你可以读更多


另一句话是你不应该打电话给eval。传递给匿名函数的参数将由jQuery解析为JSON。

这是一个问题,您必须使用JSON-p接口或在同一主机上运行的代理。

就记录而言,据我所知,您有两个问题:

  • 您没有将“jsonp”类型说明符传递给
    $.get
    ,因此它使用的是普通的XMLHttpRequest。但是,如果服务器拒绝跨域XMLHttpRequest,浏览器支持CORS(跨源资源共享)以允许跨域XMLHttpRequest。这就是
    accesscontrolalloworigin
    标题出现的地方

  • 我相信你提到你是从一个文件://URL运行它的。CORS头有两种方式来表示跨域XHR正常。一个是发送
    访问控制允许源代码:
    (如果您是通过
    $.get
    到达Flickr,他们一定是在这样做),另一个是回显
    源代码
    标题的内容。但是,
    file://
    URL会生成一个空的
    Origin
    ,无法通过回显进行授权

  • Darin建议使用
    $.getJSON
    ,以一种迂回的方式解决了第一个问题。如果在URL中看到子字符串
    callback=?
    ,那么将请求类型从默认的“json”更改为“jsonp”,这真是一个小魔术

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

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

  • 如果您试图使用JSONP,请确保以下情况之一:
    • 您正在使用
      $。获取
      并设置为
      jsonp
    • 您正在使用
      $.getJSON
      ,并将
      回调=?
      包含在URL中
  • 如果您试图通过CORS执行跨域XMLHttpRequest。。。
  • 确保您正在通过
    http://
    进行测试。通过
    file://
    运行的脚本对CORS的支持有限
  • 确保打开浏览器。(Opera和Internet Explorer迟到了)

  • 您可能需要在被调用的脚本中添加一个头,下面是我在PHP中要做的:

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

    更多详细信息请参阅(法语)。

    只要请求的服务器支持JSON数据格式,请使用JSONP(JSON填充)接口。它允许您在不使用代理服务器或花哨的头文件的情况下发出外部域请求。

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

    
    标题集访问控制允许原点“*”
    允许超越所有
    命令允许,拒绝
    通融
    

    标题集Access Control Allow Origin“*”
    中,您可以放置一个精确的URL。

    在我的例子中,相同的代码在Firefox上运行良好,但在Google Chrome上不起作用。谷歌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正确匹配,然后它就可以正常工作了。

    对于一个简单的HTML项目:

    cd project
    python -m SimpleHTTPServer 8000
    

    然后浏览您的文件。

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

    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传递给脚本。

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

    因此,搜索一点,我发现使用:

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

    作为最后一个注释

    如果标题通配符为: 访问控制允许原点:.由于访问控制允许原点明确提到, 凭证识别内容返回到调用web 内容


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

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

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

    我在Chrome中也遇到了同样的错误(我没有测试其他浏览器)。这是因为我是在domain.com上导航,而不是在www.domain.com上导航。有点奇怪,但是我可以通过在.htaccess中添加以下行来解决这个问题。它会将domain.com重定向到www.domain.com和prob
    cd project
    python -m SimpleHTTPServer 8000
    
    LoadModule proxy_module modules/mod_proxy.so
    LoadModule proxy_http_module modules/mod_proxy_http.so
    
    ProxyPass /your-proxy-url/ http://service-url:serviceport/
    
    sudo npm -g install simple-http-server # to install
    nserver # to use
    
    RewriteEngine on
    RewriteCond %{HTTP_HOST} ^domain\.com$ [NC]
    RewriteRule ^(.*)$ http://www.domain.com/$1 [R=301,L]
    
    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;
        });
    }
    
    header('Access-Control-Allow-Origin: null');