XmlHttpRequestエラー:Origin-nullはAccess-Control-Allow-Originでは許可されていません


550

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を読み込めません。Origin nullはAccess-Control-Allow-Originでは許可されていません。

ブラウザから直接その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
あなたが要求を行っていることのようなURLを見て何をからは?これは、動的に生成することが起こるしないiframeあなたのことをdocument.write例に、?
ペッカ

5
リクエストから各サービスにHTTPレスポンスを投稿できますか?PanoramioがAccess-Control-Allow-Originを提供していないに違いない。例については、w3.org / TR / corsを参照してください。
Kevin Hakanson、2010

2
@Kevin、サーバーがJSONPを送信する場合、これらのヘッダーは必要ありません。
Darin Dimitrov

@Pekka、現在、ローカルマシンからページを実行しています(file:///C:/)。関係ありませんiframe
Drew Noakes、2010

1
@drewをhttp URLから実行するとどうなりますか?この方法で違いが生じることはありませんが、可能性を排除するためです。
ペッカ

回答:


423

記録としては、私が知る限り、2つの問題がありました。

  1. 「jsonp」型指定子をに渡していない$.getため、通常のXMLHttpRequestを使用していました。ただし、ブラウザーはCORS(Cross-Origin Resource Sharing)をサポートし、サーバーがOKの場合にクロスドメインXMLHttpRequestを許可しました。そこでAccess-Control-Allow-Originヘッダーが入りました。

  2. file:// URLから実行しているとおっしゃっていたと思います。CORSヘッダーがクロスドメインXHRに問題がないことを通知する方法は2つあります。1つは送信することですAccess-Control-Allow-Origin: *(これは、を介してFlickrに到達している場合は、送信し$.getているはずです)もう1つは、Originヘッダーの内容をエコーバックすることでした。ただし、file://URLはnull Originを生成するため、エコーバックで認証することはできません。

1つ目は、Darinの使用提案により、回り道で解決されました$.getJSONcallback=?URLに部分文字列がある場合、リクエストタイプをデフォルトの「json」から「jsonp」に変更するのは少し魔法です。

これにより、file://URL からCORSリクエストを実行しないようにすることで、2番目の問題を解決しました。

他の人々のために明確にするために、ここに簡単なトラブルシューティングの手順があります:

  1. JSONPを使用する場合は、次のいずれかに該当することを確認してください。
    • を使用して$.getおり、に設定されdataTypeていjsonpます。
    • 使用$.getJSONしてcallback=?おり、URLに含まれています。
  2. CORS経由でクロスドメインXMLHttpRequestを実行しようとしている場合...
    1. 経由でテストしていることを確認してくださいhttp://。を介しfile://て実行されるスクリプトでは、CORSのサポートが制限されています。
    2. ブラウザが実際にCORSをサポートしていることを確認してください。(オペラとInternet Explorerはパーティーに遅れています)

45
これに対する解決策は何ですか?
jQuerybeast 2011

19
callback =?FTW
Tim

10
chromeなどの一部のブラウザーでは、パラメーター--allow-file-access-from-filesを使用して開始するとCORSが許可されます
echox

1
callback=?うまくいきませんでしたが、jsonp=?うまくいきました。その説明はありますか?
耳下腺炎

1
テストするためにWebサーバーをインストールする必要がありhttp://ますか?または、そのプロトコルを使用してファイルを単純に開く方法はありますか?
ウィル・シーウェル2014

76

おそらく、呼び出されたスクリプトにHEADERを追加する必要があります。これが、PHPで実行しなければならないことです。

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

で詳細クロスドメインAJAXは、サービスのWEBをOU(フランス語で)。


1
@Uri:HTTPサーバーによって異なります。Apacheでは、mod_headersを調べたいと思うでしょう。
ssokolow

4
@Uri <meta http-equiv = "Access-Control-Allow-Origin" content = "*">
Herberth Amaral 2012

7
@HerberthAmaralこれを<head> </ head>内に追加しようとしましたが、うまくいきません。iOS SafariとChromeで試してみましたが、コンソールでは、Access-Control-Allow-Originエラーでnullが許可されていません。
thandasoru 2012

3
セキュリティ上の理由から、htmlファイルの先頭では機能しません。ヘッダーでなければなりません。stackoverflow.com/questions/7015782/...
ジャスティン・ブランク

HTMLに含めることはできません。これは、HTMLページをネットワーク経由でブラウザー(いわゆるWebサーバー)に送信するプログラムで指定する必要があります。
ローマンプラシル2017年

70

単純なHTMLプロジェクトの場合:

cd project
python -m SimpleHTTPServer 8000

次に、ファイルを参照します。


1
素晴らしくて機能しているときに、0.0.0.0 POSTcode 501, message Unsupported method ('POST')8000に移動してリクエストを試行すると、Googleの場合:
pjammer 2013

「(たとえばcherypyのような)Python Webサーバーが0.0.0.0でサービスを提供していると言うとき、それは要求されたホスト名やIPに関係なく、そのマシンで終わるすべてのTCPトラフィックをリッスンしていることを意味します。」localhost:8000に投稿してみてください:stackoverflow.com/a/4341808/102022
eric.christensen

20

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=?無名関数を使用できるように私がをどのように定義しているかに注目してください。詳細については、ドキュメントをご覧ください。

もう1つの注意は、evalを呼び出さないことです。無名関数に渡されたパラメーターは、jQueryによってすでにJSONに解析されています。


うーん、もう一度試してみましょう。Chrome btw「6.0.472.51ベータ」の別のバージョンを使用しています。
Drew Noakes、2010

あなたのコードは私のために働いた。問題を引き出すコードで質問を更新しました。
Drew Noakes、2010

getJSON再先端をありがとう...私は、問題(表示するようにjsFiddle例をフォークjsfiddle.net/ZfvKmを)となりましたエラーメッセージを参照のXMLHttpRequestをロードすることはできませんpanoramio.com/wapi/data/...を。Origin fiddle.jshell.netは、Access-Control-Allow-Originでは許可されていません。
Drew Noakes、2010

@ダーリン、更新ありがとうございます。私はあなたの要点を理解し、これのいくつかの組み合わせを試しましたが、返されたオブジェクトにアクセスする方法をまだ見つけていません。jsFiddleの例を更新して、データへのアクセスを表示できますか?コールバックをに設定した場合?、返されるJSONは括弧で囲まれます。コールバック関数のパラメーターを定義しておらず、の値にthis応答オブジェクトがないようです(少なくとも、.data値はですnull)。
Drew Noakes、2010

@ダーリン、素晴らしい。どうもありがとう。今はうまくいきます。これを読んでいる人は誰でも、を含めると、callback=?jQueryにランダムな関数名を内部的に生成するように指示され、結果として、渡した無名関数が呼び出されます.getJSON。感謝。
Drew Noakes、2010

8

要求されたサーバーがJSONデータ形式をサポートしている限り、JSONP(JSON Padding)インターフェイスを使用します。プロキシサーバーや特別なヘッダーを使用せずに、外部ドメイン要求を行うことができます。



4

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を指定できます。


1
これはXAMPPのApacheでは機能しません。問題はまだ存在しています。
ラプター2013年

1
これは安全ではありません。理由はこちらをご覧ください。stackoverflow.com/questions/7564832/...
ロブ・

@RobQuistが言ったように安全ではありません。
d337

4

ローカルテストを行っている場合、またはそのようなものからファイルを呼び出している場合、file://ブラウザのセキュリティを無効にする必要があります。

MACの場合: open -a Google\ Chrome --args --disable-web-security


3

私の場合、同じコードは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"

元のURLと正しく一致させるには、Ajax URLのwww部分を削除する必要があり、その場合は問題なく動作しました。


2

すべてのサーバーが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;
    });
}

1

私は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をスクリプトに渡します。


1

最後に、Mozillaのドキュメントには

上記の例は、ヘッダーがAccess-Control-Allow-Origin:*のようにワイルドカード化されていると失敗し ます。 Access-Control-Allow-Originはhttp://foo.exampleに明示的に言及しているため、資格情報認識コンテンツは呼び出し元のWebコンテンツに返されます。

結果として、「*」を使用することは単に悪い習慣ではありません。単に動作しません:)


1

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

file://でaxios call php live servicesを使用する


これは私からも機能します。nullは文字列であり、実際のNULLではないことに注意してください。私はそれをheader('Access-Control-Allow-Origin: '.( trim($_SERVER['HTTP_REFERER'],'/') ?:'null'),true);リモートサーバーから別のサーバーへのクロスオリジンを許可し、ローカルファイルの場合は(文字列)nullに該当するものとして使用します。
Louis Loudog Trottier

0

Chromeでも同じエラーが発生しました(他のブラウザーはテストしていません)。これは、www.domain.comではなくdomain.comに移動していたためです。少し奇妙ですが、.htaccessに次の行を追加することで問題を解決できました。domain.comをwww.domain.comにリダイレクトし、問題は解決しました。私は怠惰なWeb訪問者なので、wwwを入力することはほとんどありませんが、場合によっては必須であるようです。

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


0

フォーク、

私は同様の問題に遭遇しました。しかし、Fiddlerを使用して、この問題に対処することができました。問題は、Web API側のCORS実装で構成されているクライアントURLに末尾のスラッシュがあってはならないことです。Google Chrome経由でリクエストを送信し、ヘッダーのTextViewタブを検査した後 Fiddlerのセクションのと、エラーメッセージは次のようになります。

*「指定されたポリシーの起点your_client_url:/ 'は無効です。スラッシュで終了することはできません。」

これはInternet Explorerで問題なく動作したので本当に風変わりですが、Google Chromeを使用してテストするときに頭痛の種を与えました。

CORSコードのフォワードスラッシュを削除してWeb APIを再コンパイルしましたが、ChromeとInternet Explorerから問題なくAPIにアクセスできます。これを試してみてください。

ありがとう、アンディ


0

上記のCodeGrooverによって投稿さたソリューションには小さな問題があり、ファイルを変更した場合、更新されたファイルを実際に使用するにはサーバーを再起動する必要があります(少なくとも私の場合)。

だから少し検索して、私はこれを見つけました使用するには:

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

そしてそれはで役立つでしょうhttp://localhost:8000


1
このリンクで質問に答えることができますが、回答の重要な部分をここに含め、参照用のリンクを提供することをお勧めします。リンクされたページが変更されると、リンクのみの回答が無効になる可能性があります。- レビューから
-Vi100

リンクを明確にしました。
MiJyn 2018
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.