jQuery AJAXクロスドメイン


477

ここにtest.phpとtestserver.phpの2つのページがあります。

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とlocalhost上のtest.phpは、機能せず、alert("Error")実行中です。ajax内のURLがhttp://domain.com/path/to/file/testserver.phpに変更されても


38
立ち寄る人のために。クロスドメインのJavaScriptが作業呼び出す方法のアイデア持っているために、これを読んでstackoverflow.com/a/11736771/228656を
アブドゥルMunim

1
私はこの質問に対する回答をここに書きました:jQuery AJAXを使用したクロスドメインHTMLページのロード最後の1つはhttpsをサポートします
jherax

回答:


412

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()は省略形のメソッドですが'callback=?'、GETパラメータとしてURL に追加する必要があります(はい、値は?、jQueryはこれを独自に生成したコールバックメソッドで置き換えます)。


2
callbackName('/* json */')代わりに戻る必要があるのはなぜcallbackName(/* json */)ですか?
Eric

3
@ericコールバックはJSON文字列を想定しています。理論的には、オブジェクトも同様に機能する可能性がありますが、jQueryがこれにどのように応答するかわからない場合、エラーがスローされるか、警告なしに失敗する可能性があります。
BGerrissen、2011年

次のエラーが発生します。SyntaxError:行方不明; ステートメント{"ResultCode":2}の前。ここで、{"ResultCode":2}は応答です。アドバイスを下さい。
user2003356 2014年

@ user2003356は、JSONPではなくプレーンJSONを返すようです。次のようなものを返す必要があります:callbackFunction({"ResultCode":2})。jQueryは、GETパラメータ「callback」をリクエストに追加します。これは、jqueryが使用するコールバック関数の名前であり、応答に追加する必要があります。
BGerrissen 2014

2
それは2016年です。JSONPがハックとしてのみ記述できるのとは対照的に、CORSは現在広くサポートされている標準です。以下の@joshuarhの回答が、今のところ優先されるはずです。
Vicky Chijwani

202

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を参照してください


12
Jsonpは投稿、書き込み、削除をサポートしていませんでした。あなたのソリューションは素晴らしい働きをします。
TonyTakeshi 2012

35
PHPヘッダー( "Access-Control-Allow-Origin:*");
SparK 2012

9
@Warrior jQueryの.post()メソッドを使用している場合は、jQueryでクロスドメインサポートを有効にする必要があります。これは次のように行われます$.support.cors = true
Friederike 2013

21
この方法でサーバーを構成すると、セキュリティにどのような影響がありますか?
Jon Schneider

19
ワイルドカード "*"を使用するのではなく、データを共有するドメインのみを許可することをお勧めします。
セバスティアンGrignoli

32

Access-Control-Allow-Originを追加することで、HTTPヘッダーを介してこれを制御できます。これを*に設定すると、任意のドメインからのクロスドメインAJAXリクエストが受け入れられます。

PHPを使用するのは非常に簡単です。次の行をスクリプトに追加して、ドメインの外部からアクセスできるようにします。

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

httpd.confでmod_headersモジュールを有効にすることを忘れないでください。


あなたは私の日を救った。
NomanJaved

20

同一生成元ポリシーを確認する必要があります。

コンピューティングでは、同じ生成元ポリシーが、JavaScriptなどの多くのブラウザー側プログラミング言語の重要なセキュリティ概念です。このポリシーは、同じサイトからのページで実行されるスクリプトが特定の制限なしに互いのメソッドとプロパティにアクセスすることを許可しますが、異なるサイトのページにあるほとんどのメソッドとプロパティにはアクセスできません。

データを取得できるようにするには、次の条件が必要です。

同じプロトコルとホスト

それを回避するには、JSONPを実装する必要があります。


17

ローカルディスク「file:/// C:/test/htmlpage.html」からWebページをロードし、「http://localhost/getxml.php」URLを呼び出し、これをIE8 +およびFirefox12 +ブラウザーで実行し、jQuery v1を使用する必要がありました。ボイラープレートコードを最小限に抑えるための.7.2 lib。数十の記事を読んだ後、ついにそれを理解しました。これが私の要約です。

  • サーバースクリプト(.php、.jspなど)は、http応答ヘッダーAccess-Control-Allow-Originを返す必要があります:*
  • jQuery ajaxを使用する前に、javascriptでこのフラグを設定します。jQuery.support.cors = true;
  • jQuery ajax関数を使用する前に、フラグを1回または毎回設定できます
  • IEとFirefoxで.xmlドキュメントを読むことができるようになりました。私がテストしなかった他のブラウザ。
  • 応答ドキュメントは、プレーン/テキスト、xml、json、またはその他のものにすることができます

以下は、いくつかのデバッグ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);
    }
});

1
私はこの質問に対する回答をここに書きました:jQuery AJAXを使用したクロスドメインhtmlページのロード最後の1つはhttpsをサポートします
jherax

firestポイントの場合:PHPのスクリプトに次の行を追加しますheader("Access-Control-Allow-Origin: *");
T30

1
@whome回答ありがとうございます。あなたは私をたくさん助けてくれました。乾杯。
Luis Milanese

10

同一生成元ポリシーにより、JavaScriptがドメイン間でリクエストを行うことができないのは事実ですが、CORS仕様では、探している種類のAPIアクセスのみを許可しており、主要なブラウザーの現在のバッチでサポートされています。

クライアントとサーバーのクロスオリジンリソース共有を有効にする方法をご覧ください。

http://enable-cors.org/

「クロスオリジンリソースシェアリング(CORS)は、ドメイン境界を越えて真にオープンなアクセスを可能にする仕様です。パブリックコンテンツを提供する場合は、CORSを使用してユニバーサルJavaScript /ブラウザアクセス用にオープンすることを検討してください。」



9

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




4

Jqueryドキュメントから(リンク):

  • ブラウザのセキュリティ制限により、ほとんどの「Ajax」リクエストは同じオリジンポリシーの対象になります。リクエストは、別のドメイン、サブドメイン、またはプロトコルからデータを正常に取得できません。

  • スクリプトおよびJSONPリクエストは、同じオリジンポリシー制限の対象ではありません。

そのため、リクエストにjsonpを使用する必要があると考えます。しかし、これを自分で試したことはありません。


2

私はあなたの問題を解決する3つの方法を知っています:

  1. まず、両方のドメインにアクセスできる場合は、次を使用して他のすべてのドメインへのアクセスを許可できます。

    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>

  2. サーバーのphpファイルへのajaxリクエストを取得し、このphpファイルを使用して別のドメインへのリクエストを処理できます。

  3. 許可を必要としないため、jsonpを使用できます。これについては、友達の@BGerrissenの回答を読むことができます。

0

Microsoft Azureの場合は少し異なります。

Azureには、設定が必要な特別なCORS設定があります。これは本質的には裏で同じことですが、joshuarhが言及するヘッダーを設定するだけでは機能しません。クロスドメインを有効にするためのAzureドキュメントは、次の場所にあります。

https://docs.microsoft.com/en-us/azure/app-service-api/app-service-api-cors-consume-javascript

ホスティングプラットフォームにこの特別な設定があることに気づく前に、私はこれを数時間いじっていました。


0

それは機能し、必要なものはすべて:

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 }
});
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.