これが2つのページ、test.phpとtestserver.phpです。
test.php
<script src="scripts/jq.js" type="text/javascript"></script>
<script>
$(function() {
$.ajax({url:"testserver.php",
success:function() {
alert("Success");
},
error:function() {
alert("Error");
},
dataType:"json",
type:"get"
}
)})
</script>
testserver.php
<?php
$arr = array("element1",
"element2",
array("element31","element32"));
$arr['name'] = "response";
echo json_encode($arr);
?>
今私の問題:これらのファイルの両方が同じサーバー(localhostまたはWebサーバー)にあるとき、それは機能し、alert("Success")
が呼び出されます。異なるサーバー上にある場合、つまりWebサーバー上のtestserver.phpとローカルホスト上のtest.phpは機能しておらず、alert("Error")
は実行中です。 ajax内のURLが http://domain.com/path/to/file/testserver.php に変更されても
_ jsonp _ を使用してください。
jQuery:
$.ajax({
url:"testserver.php",
dataType: 'jsonp', // Notice! JSONP <-- P (lowercase)
success:function(json){
// do stuff with json (in this case an array)
alert("Success");
},
error:function(){
alert("Error");
}
});
PHP:
<?php
$arr = array("element1","element2",array("element31","element32"));
$arr['name'] = "response";
echo $_GET['callback']."(".json_encode($arr).");";
?>
エコーは間違っているかもしれません、私がphpを使ってからもうしばらくの間です。どのような場合でも、引用符に注意してcallbackName('jsonString')
を出力する必要があります。 jQueryはそれ自身のコールバック名を渡すので、GETパラメータから取得する必要があります。
Stefan Kendallが投稿したように、 $ .getJSON() は短縮形のメソッドですが、GETパラメータとして'callback=?'
をURLに追加する必要があります(はい、値は?、jQueryはこれを独自の生成コールバックメソッドで置き換えます)。 。
JSONPは良い選択肢ですが、もっと簡単な方法があります。あなたは単にあなたのサーバ上でAccess-Control-Allow-Origin
ヘッダを設定することができます。 *
に設定すると、どのドメインからのクロスドメインAJAXリクエストも受け付けます。 ( https://developer.mozilla.org/en/http_access_control )
これを行う方法は、もちろん言語によって異なります。これはRailsにあります。
class HelloController < ApplicationController
def say_hello
headers['Access-Control-Allow-Origin'] = "*"
render text: "hello!"
end
end
この例では、say_hello
アクションは任意のドメインからのAJAX要求を受け入れ、 "hello!"という応答を返します。
これは返すかもしれないヘッダの例です:
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Type: text/html; charset=utf-8
X-Ua-Compatible: IE=Edge
Etag: "c4ca4238a0b923820dcc509a6f75849b"
X-Runtime: 0.913606
Content-Length: 6
Server: WEBrick/1.3.1 (Ruby/1.9.2/2011-07-09)
Date: Thu, 01 Mar 2012 20:44:28 GMT
Connection: Keep-Alive
それは簡単です、それはいくつかのブラウザの制限があります。 http://caniuse.com/#feat=cors を参照してください。
Access-Control-Allow-Origin を追加することで、HTTPヘッダーを介してこれを制御できます。 *に設定すると、どのドメインからのクロスドメインAJAX要求も受け付けます。
_ php _ を使うのはとても簡単です。自分のドメインの外部からアクセスしたいスクリプトに次の行を追加するだけです。
header("Access-Control-Allow-Origin: *");
Httpd.confでmod_headersモジュールを有効にすることを忘れないでください。
同じオリジンポリシー :を確認する必要があります。
コンピューティングでは、同じOriginポリシーが、JavaScriptなどのブラウザサイドプログラミング言語の多くにとって重要なセキュリティ概念です。このポリシーは、同じサイトから発生したページで実行されているスクリプトが特に制限なしに互いのメソッドやプロパティにアクセスすることを許可しますが、異なるサイトのページにまたがってほとんどのメソッドやプロパティにアクセスすることを防ぎます。
データを取得できるようにするには、次の条件を満たす必要があります。
同じプロトコルとホスト
これを回避するには _ jsonp _ を実装する必要があります。
ローカルディスク "file:/// C:/test/htmlpage.html"からWebページをロードし、 "http://localhost/getxml.php" URLを呼び出して、IE 8以降およびFirefox 12以降のブラウザでこれを行う必要があります。jQueryv1を使用.7.2定型コードを最小化するためのlib。何十もの記事を読んだ後、ついにそれを考え出しました。これが私の要約です。
これはいくつかのdebug sysoutを使ったjQuery ajax呼び出しの例です。
jQuery.support.cors = true;
$.ajax({
url: "http://localhost/getxml.php",
data: { "id":"doc1", "rows":"100" },
type: "GET",
timeout: 30000,
dataType: "text", // "xml", "json"
success: function(data) {
// show text reply as-is (debug)
alert(data);
// show xml field values (debug)
//alert( $(data).find("title").text() );
// loop JSON array (debug)
//var str="";
//$.each(data.items, function(i,item) {
// str += item.title + "\n";
//});
//alert(str);
},
error: function(jqXHR, textStatus, ex) {
alert(textStatus + "," + ex + "," + jqXHR.responseText);
}
});
Same-originポリシーはJavaScriptがドメイン間でリクエストを行うことを防ぎますが、CORS仕様はあなたが探している種類のAPIアクセスだけを許可し、現在の主要なブラウザのバッチによってサポートされています。
クライアントとサーバーでクロスオリジンリソース共有を有効にする方法を参照してください。
「Cross-Origin Resource Sharing(CORS)は、ドメインの境界を越えた真のオープンアクセスを可能にする仕様です。パブリックコンテンツを提供する場合は、CORSを使用してユニバーサルJavaScript /ブラウザアクセス用に開くことを検討してください。」
これは可能ですが、JSONではなくJSONPを使用する必要があります。 Stefanのリンクはあなたを正しい方向に向けています。 JSONPの詳細については、 jQuery AJAX page を参照してください。
Remy Sharpには 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をスクリプトに渡します。
ブラウザのセキュリティにより、あるドメインでホストされているページから別のドメインでホストされているページへのajax呼び出しが防止されます。これは " 同じオリジンポリシー "と呼ばれます。
エラー処理を含むJSONPの使用例はいくつかあります。
ただし、JSONPを使用するとerror-eventがトリガーされないことに注意してください。参照してください: http://api.jquery.com/jQuery.ajax/ または jsonpエラーを使用したjQuery ajaxリクエスト
Jqueryのドキュメント( link )から:
ブラウザのセキュリティ制限により、ほとんどの "Ajax"リクエストは同じOriginポリシーの対象となります。要求は、異なるドメイン、サブドメイン、またはプロトコルからデータを正常に取得できません。
スクリプト要求とJSONP要求は、同じOriginポリシー制限の対象にはなりません。
そのため、リクエストにはjsonpを使用する必要があると考えます。しかし、これを自分で試したことはありません。
私はあなたの問題を解決する3つの方法を知っています:
まず両方のドメインにアクセスできる場合は、他のすべてのドメインへのアクセスを許可できます。
header("Access-Control-Allow-Origin: *");
または単に.htaccessファイルに以下のコードを追加してドメインを追加します。
<FilesMatch "\.(ttf|otf|eot|woff)$"> <IfModule mod_headers.c> SetEnvIf Origin "http(s)?://(www\.)?(google.com|staging.google.com|development.google.com|otherdomain.net|dev02.otherdomain.net)$" AccessControlAllowOrigin=$0 Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin </IfModule> </FilesMatch>
あなたはあなたのサーバーのphpファイルへのajaxリクエストを持ち、このphpファイルを使って他のドメインへのリクエストを処理することができます。
それはうまくいきます、あなたが必要とするすべて:
PHP:
header('Access-Control-Allow-Origin: http://www.example.com');
header("Access-Control-Allow-Credentials: true");
header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');
JS(jQuery ajax):
var getWBody = $.ajax({ cache: false,
url: URL,
dataType : 'json',
type: 'GET',
xhrFields: { withCredentials: true }
});
Microsoft Azureの場合は、少し異なります。
Azureには、設定が必要な特別なCORS設定があります。これは基本的には基本的に同じことですが、単にjoshuarhというヘッダーを設定してもうまくいきません。クロスドメインを有効にするためのAzureドキュメントは、こちらにあります。
https://docs.Microsoft.com/ja-jp/Azure/app-service-api/app-service-api-cors-consume-javascript
私のホスティングプラットフォームにこの特別な設定があることに気づく前に、私は数時間これをいじっていました。