2011-06-18 27 views
30

私はjQueryの$.getJSON()関数をjusingデータの短いセットを返すjusingしています。jQuery.getJSON - アクセス制御許可Origin問題

私は、JSONデータをexample.comのようなURLに置いています。 私はそれを認識しませんでしたが、同じURLにアクセスしているときに、JSONデータをロードできませんでした。私はコンソールをたどり、Access-Control-Allow-OriginのためにXMLHttpRequestが読み込めないことを発見しました。

ここでは、ちょうど$.getJSON()を使用すると言われている多くのサイトを読んだことがありますが、それは回避策ですが、明らかに動作しませんでした。ヘッダーや関数の中で何か変更する必要がありますか?

お願いします。

+2

おそらくJSONP:http://en.wikipedia.org/wiki/JSONPを見てみるとよいでしょう。 – pimvdb

+0

代わりに、利用可能な場合は、プロキシ(PHPカールなど)を使用してリクエストと応答を転送することもできます。 – Dan

答えて

36

JSON-Pを代わりに使用したいと思うかもしれません(下記参照)。最初に簡単な説明。

上記のヘッダーはCross Origin Resource Sharing標準のものです。他のブラウザ(Microsoftのsigh)では、jQueryが使用する標準のXMLHttpRequestではなく、特別なオブジェクト(XDomainRequest)を使用する必要があることに注意してください。また、サーバー側のリソースを明示的に他の起点(www.xxxx.com)を許可するように変更する必要があります。あなたが要求しているJSONデータを取得するために

が、あなたは基本的に3つのオプションがあります。可能であれば

  1. を、あなたがロードしているファイルの位置を補正することにより、最大限に互換できるように、彼らが持っています読み込んだドキュメントと同じ起点です。 (私はAjax経由でロードする必要があると仮定しているため、Same Origin Policyの問題が表示されます)

  2. JSON-PはSOPの対象外です。 jQueryには、ajaxコールでのサポートが組み込まれています(ちょうどdataTypeを "jsonp"に設定し、jQueryはすべてのクライアント側の作業を行います)。これにはサーバー側の変更が必要ですが、それほど大きな変更は必要ありません。基本的にJSONレスポンスを生成しているものは、「callback」というクエリ文字列パラメータを探し、その関数を呼び出すJavaScriptコードでJSONをラップします。例えば、あなたの現在のJSON応答がある場合:

    {"weather": "Dreary start but soon brightening into a fine summer day."} 
    

    あなたのスクリプトは、「コールバック」クエリ文字列パラメータを探します(のパラメータの値が「jsop123」であるとする)およびJavaScriptの構文にJSONことをラップします関数呼び出し:

    jsonp123({"weather": "Dreary start but soon brightening into a fine summer day."}); 
    

    これはそれです。 JSON-Pは非常にです(JavaScript scriptタグで動作するため)。 JSON-PはGETのみですが、POSTではなく、scriptタグで動作します。

  3. CORS(あなたが引用したヘッダーに関連するメカニズム)を使用してください。 the specification linked aboveの詳細ですが、基本的には

    です。A.ブラウザは、OPTIONS HTTP動詞(方法)を使用してサーバーに「プリフライト」メッセージを送信します。GETまたはPOSTで送信されるさまざまなヘッダーと、ヘッダー "Origin"、 "Access-Control-Request-Method"(例:GETまたはPOST)、および "Access-Control-Request-Headers" (送信したいヘッダー)。

    B.あなたのPHPは、その情報に基づいて、要求が大丈夫かどうかを判断し、「アクセス制御許可元」、「アクセス制御許可方式」、「アクセス制御許可方式」で応答するかどうかを判断します。 Control-Allow-Headers "ヘッダーの値を許可します。あなたは、その応答を持った身体(ページ)を送ることはありません。

    C.ブラウザはあなたの応答を確認し、実際にGETまたはPOSTを送信することが許可されているかどうかを確認します。そうであれば、「Origin」とさまざまな「Access-Control-Request-xyz」ヘッダーを使用してその要求を再度送信します。

    D.あなたのPHPは、これらのヘッダを調べて、をもう一度確認します。 擬似 -codeで

    (私は多くのPHPを行っていないので、私はここにPHPの文法をやろうとしていないよ):

    // Find out what the request is asking for 
    corsOrigin = get_request_header("Origin") 
    corsMethod = get_request_header("Access-Control-Request-Method") 
    corsHeaders = get_request_header("Access-Control-Request-Headers") 
    if corsOrigin is null or "null" { 
        // Requests from a `file://` path seem to come through without an 
        // origin or with "null" (literally) as the origin. 
        // In my case, for testing, I wanted to allow those and so I output 
        // "*", but you may want to go another way. 
        corsOrigin = "*" 
    } 
    
    // Decide whether to accept that request with those headers 
    // If so: 
    
    // Respond with headers saying what's allowed (here we're just echoing what they 
    // asked for, except we may be using "*" [all] instead of the actual origin for 
    // the "Access-Control-Allow-Origin" one) 
    set_response_header("Access-Control-Allow-Origin", corsOrigin) 
    set_response_header("Access-Control-Allow-Methods", corsMethod) 
    set_response_header("Access-Control-Allow-Headers", corsHeaders) 
    if the HTTP request method is "OPTIONS" { 
        // Done, no body in response to OPTIONS 
        stop 
    } 
    // Process the GET or POST here; output the body of the response 
    

    は再び、これは擬似コードであることを強調しました。

+0

jQueryを利用してこれを行う方法はありますか?または、私はこの仕事をさせる(PHP経由で)設定できるヘッダーがありますか? – Mike

+0

@Mike:どちら "これ"?はい、JSON-Pを意味するなら、jQueryはその 'ajax'呼び出しをサポートしています。私は上記のいくつかの詳細を追加しました。あなたがCORSを意味するならば、それは 'OPTIONS' HTTPリクエストに応じてPHP経由で設定し、' GET'や 'POST'に応じて設定したヘッダです。私はそれについてもいくつかの詳細を追加しました。しかし、ファイルを移動して同じ起源になる可能性がある場合は、残念です。 –

+0

@ T.J.Crowderだから$ .getJSONは機能しません。 ajaxのような他のメソッドを使用してヘッダーを設定する必要がありますか? – Dinesh

66

それは簡単ですが、$.getJSON()機能を使用し、URLにちょうど

コールバックを含めますか=?

をパラメータとする。これにより、クロスドメイン・コールを行うために必要なJSONPへのコールが変換されます。さらに詳しい情報:http://api.jquery.com/jQuery.getJSON/

+18

それはまったく依存しますサーバは、すべての場合にそうでない可能性のある余分なコールバックパラメータを受け入れます。 – Simon

+7

これは、サーバーがjsonpサーバーに設定されていないかのように100%時間稼働しない場合でも、エラーが発生するjsonを返します。 – chadpeppers

+1

それは私のために働く感謝! – FrontENG