私は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 。 Origin nullはAccess-Control-Allow-Originでは許可されていません。
私がブラウザから直接その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
これを助けてくれたDarinに感謝します。 上記のコードIS間違っています。 代わりにこれを使ってください:
$().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...
});
});
記録に関しては、私が言うことができる限り、あなたは2つの問題を抱えていました:
あなたはあなたの$.get
に "jsonp"型指定子を渡していなかったので、普通のXMLHttpRequestを使っていました。ただし、ご使用のブラウザはCORS(Cross-Origin Resource Sharing)をサポートしており、サーバーが問題なければクロスドメインXMLHttpRequestを許可します。それがAccess-Control-Allow-Origin
ヘッダーが入ったところです。
私はあなたがfile:// URLからそれを実行していたと言ったと思います。クロスドメインXHRが問題ないことをCORSヘッダが通知する方法は2つあります。 1つはAccess-Control-Allow-Origin: *
を送信することです(これは、$.get
を介してFlickrにアクセスしている場合は、行っているはずです)。もう1つはOrigin
ヘッダーの内容をエコーバックすることです。しかし、file://
のURLは、エコーバックでは承認できないnullのOrigin
を生成します。
最初の問題は、$.getJSON
を使用するというDarinの提案によって、迂回方法で解決されました。 URLにサブストリングcallback=?
がある場合は、要求タイプをデフォルトの "json"から "jsonp"に変更するのは少し不思議です。
これは、file://
のURLからCORS要求を実行しようとしなくなることで、2番目の問題を解決しました。
他の人々を明確にするために、ここに簡単なトラブルシューティングの指示があります:
$.get
を使用しており、 dataType
をjsonp
に設定します。$.getJSON
を使用していて、URLにcallback=?
を含めました。http://
でテストしていることを確認してください。 file://
を介して実行されるスクリプトは、CORSを限定的にしかサポートしていません。呼び出されたスクリプトにHEADERを追加する必要があるかもしれません。これは、PHPで実行しなければならなかったことです。
header('Access-Control-Allow-Origin: *');
詳細はクロスドメインAJAXouサービス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);
});
また、IE8では(少なくとも私のマシンでは)上記の方法では動作しないため、代わりに $.getJSON()
メソッドを使用することをお勧めします。
$.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)インターフェースを使用してください。それはあなたがプロキシサーバーや空想のヘッダのものなしで外部ドメインのリクエストをすることを可能にします。
これは 同じOriginポリシーです 、同じホスト上で実行されている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部分をOriginの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/
最後に、proxy-urlをスクリプトに渡します。
最後の注意として、 Mozillaのドキュメントには明示的に thatと書かれています。
上記の例は、ヘッダーが次のようにワイルドカード化されていると失敗します。 Access-Control-Allow-Origin:*。 Access-Control-Allow-Originは http://foo.example を明示的に記述しているので、認証情報を認識しているコンテンツは呼び出し側のWebコンテンツに返されます。
結果として、 '*'を使用することは単なる悪い習慣ではありません。単に動作しません:)
PHPの場合-これはChrome、Safari、Firefoxで動作します
header('Access-Control-Allow-Origin: null');
axiosを使用してfile://でPHPライブサービスを呼び出します
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]
最新バージョンのJQueryを使用していることを確認してください。 JQuery 1.10.2でこのエラーに直面していましたが、JQuery 1.11.1を使用した後にエラーが解決しました
上のCodeGrooverによって投稿されたソリューションには小さな問題があります ファイルを変更した場合、実際に更新されたファイルを使用するにはサーバーを再起動する必要があります(少なくとも私の場合)。
それでちょっと検索して、私は これを見つけました 使用するには:
Sudo npm -g install simple-http-server # to install
nserver # to use
そしてそれはhttp://localhost:8000
で機能します。
みんな、
私は同様の問題に遭遇しました。しかし、Fiddlerを使用して、私は問題を解決することができました。問題は、Web API側のCORS実装で設定されているクライアントURLの末尾にスラッシュがあってはいけないことです。 Google Chromeでリクエストを送信し、Fiddlerの Headers セクションの TextView タブを調べると、エラーメッセージに次のような内容が表示されます。
* "指定されたポリシーOrigin your_client_url:/ 'は無効です。 スラッシュで終わらせることはできません。"
Internet Explorerでは問題なく動作していましたが、Google Chromeを使用してテストするときに頭痛がしたので、これは本当に奇妙です。
CORSコードのスラッシュを削除してWeb APIを再コンパイルしたところ、このAPIにはChromeとInternet Explorerから問題なくアクセスできます。これを撃ってください。
ありがとう、アンディ