簡體   English   中英

對於從 file:// URL 運行的應用程序發出的請求,“Access-Control-Allow-Origin 不允許使用 Origin null”錯誤

[英]“Origin null is not allowed by Access-Control-Allow-Origin” error for request made by application running from a file:// URL

我正在開發一個頁面,通過 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 沒有在錯誤消息中找到任何有用的匹配項。

編輯

下面是一些顯示問題的示例代碼:

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

感謝 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...
  });
});

作為記錄,據我所知,您有兩個問題:

  1. 您沒有將“jsonp”類型說明符傳遞給您的$.get ,因此它使用的是普通的 XMLHttpRequest。 但是,您的瀏覽器支持 CORS(跨域資源共享)以允許跨域 XMLHttpRequest,如果服務器通過了它。 這就是Access-Control-Allow-Origin標頭出現的地方。

  2. 我相信您提到您是從 file:// URL 運行它的。 CORS 標頭有兩種方式來表示跨域 XHR 正常。 一種是發送Access-Control-Allow-Origin: * (如果您通過$.get到達 Flickr,他們肯定已經這樣做了),而另一種是回顯Origin標頭的內容。 但是, file:// URL 會產生一個無法通過回顯授權的空Origin

Darin 建議使用$.getJSON以迂回的方式解決了第一個問題。 如果它看到子字符串callback=? 在網址中。

通過不再嘗試從file:// URL 執行 CORS 請求,解決了第二個問題。

為了向其他人澄清,這里是簡單的故障排除說明:

  1. 如果您嘗試使用 JSONP,請確保是以下情況之一:
    • 您正在使用$.get並將dataType設置為jsonp
    • 您正在使用$.getJSON並包含callback=? 在網址中。
  2. 如果您嘗試通過 CORS 執行跨域 XMLHttpRequest ...
    1. 確保您正在通過http://進行測試。 通過file://運行的腳本對 CORS 的支持有限。
    2. 確保瀏覽器確實支持 CORS (Opera 和 Internet Explorer 遲到了)

您可能需要在被調用的腳本中添加一個 HEADER,這是我必須在 PHP 中執行的操作:

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

跨域 AJAX ou services WEB (法語)中的更多詳細信息。

對於一個簡單的 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=? 以便您可以使用匿名函數。 您可以在文檔中閱讀更多相關信息

另一個注意事項是你不應該調用 eval。 傳遞給匿名函數的參數已經被 jQuery 解析為 JSON。

只要請求的服務器支持JSON數據格式,就使用JSONP(JSON Padding)接口。 它允許您在沒有代理服務器或花哨的標題內容的情況下發出外部域請求。

如果您正在進行本地測試或從file://類的東西調用文件,那么您需要禁用瀏覽器安全性。

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

這是同源策略,您必須使用 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。

就我而言,相同的代碼在 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 正確匹配,然后它工作正常。

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

最后一點, Mozilla 文檔明確指出

如果標頭被通配為: Access-Control-Allow-Origin: *. 由於 Access-Control-Allow-Origin 明確提到http://foo.example ,憑據認知內容將返回給調用 Web 內容。

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

對於 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 實時服務

我使用 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 傳遞給您的腳本。

上面 CodeGroover發布的解決方案中有一個小問題,如果您更改文件,則必須重新啟動服務器才能實際使用更新的文件(至少在我的情況下)。

所以搜索了一下,我找到了這個來使用:

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

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

我在 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 后該錯誤得到了解決

各位,

我遇到了類似的問題。 但是使用 Fiddler,我能夠解決這個問題。 問題是在 Web API 端的 CORS 實現中配置的客戶端 URL 不能有尾部正斜杠。 通過谷歌瀏覽器提交您的請求並檢查 Fiddler標題部分的TextView選項卡后,錯誤消息如下所示:

*“指定的策略來源 your_client_url:/' 無效。它不能以正斜杠結尾。”

這真的很奇怪,因為它在 Internet Explorer 上運行沒有任何問題,但在使用 Google Chrome 進行測試時讓我頭疼。

我刪除了 CORS 代碼中的正斜杠並重新編譯了 Web API,現在可以通過 Chrome 和 Internet Explorer 訪問該 API,沒有任何問題。 請試一試。

謝謝,安迪

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM