10

ajaxを介してjsonを受信する際に問題が発生しました。エラーは以下のとおりです。エラーに関してこれまでに見つけた情報によると、これはある種のクロスドメインの問題のようですが、それが何を意味し、どのように解決するのかわかりません。

応答ヘッダーに問題がある可能性があります(私はAPIを自分で作成し、以前から経験がありません)が、ブラウザーでURLに直接アクセスすると200OKが受信されます。

ブラウザでURLに直接アクセスする場合、有効なjsonが表示されるので、問題はありません。

これはどのように解決できますか?

注:URLはApacheサーバーに送信されますが、この問題について読んだStackの質問の95%に当てはまるファイルではありません。

インスペクターのエラー:

XMLHttpRequest cannot load http://localhost/api/v1/products?_=1355583847077.
Origin null is not allowed by Access-Control-Allow-Origin.
Error: error 

コード:

    $.ajaxSetup ({
      url: "http://localhost/api/v1/products", // <--- returns valid json if accessed in the browser
      type: "GET",
      dataType: "json",
      cache: false,
      contentType: "application/json"
    })
    $.ajax({
        success: function(data){

            console.log("You made it!");
        },
        error: function(xhr) {
           console.log("Error: " + xhr.statusText);
       }
    }).done(function(data){
        console.log(data);
    })

パラメータ

_ 1355583610778

ヘッダー

応答ヘッダー:

Connection  Keep-Alive
Content-Length  3887
Content-Type    application/json
Date    Sat, 15 Dec 2012 14:50:53 GMT
Keep-Alive  timeout=5, max=100
Server  Apache/2.2.14 (Unix) DAV/2 mod_ssl/2.2.14 OpenSSL/0.9.8l PHP/5.3.1 mod_perl/2.0.4 Perl/v5.10.1
X-Powered-By    PHP/5.3.1

リクエストヘッダー:

Accept  application/json, text/javascript, */*; q=0.01
Accept-Encoding gzip, deflate
Accept-Language sv-SE,sv;q=0.8,en-US;q=0.5,en;q=0.3
Connection  keep-alive
Host    localhost
Origin  null
User-Agent  Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:17.0) Gecko/17.0 Firefox/17.0

応答

ここには何もない...

4

5 に答える 5

20

はい、これは間違いなくクロスドメインの問題です。しかし、心配しないでください。この問題には 2 つの解決策があります。

JSONP の使用

サーバーで JSONP (パディング付きの JSON) のサポートを実装できます (つまり、Fergus Morrow のソリューション)。JSONP はクロスドメインですぐに使用でき、基本的に JSON に関数呼び出しが埋め込まれています。

.ajaxSetupセット内dataTypeで、サーバー側で、リクエストで指定されjsonpた url パラメータを確認する必要があります。callbackそのパラメーターが設定されている場合、それに応じて JSON 応答をパディングする必要があります。

parseThis({ "json": "can", "be": "put", "in": "here" });

上記はcallbackが に設定されていることを前提としていparseThisます。jQuery はデフォルトで関数名を生成しますが、 の値を設定することでこれをオーバーライドできjsonpCallbackます.ajaxSetup

?callback=?ショートカットを使用して、リクエスト URLに追加するだけで、JSONP をリクエストしていることを jQuery に伝えることもできます。

Access-Control-Allow-Origin の使用

別の解決策はAccess-Control-Allow-Origin、応答にヘッダーを設定することです。

Access-Control-Allow-Origin: *

上記により、任意のリソースがサービスのクロスドメインを使用できるようになります。設定方法の詳細については、以下にリンクされている記事を参照してくださいAccess-Control-Allow


Access-Control-Origin と CORS について詳しく知りたい場合は、 MDN のこの記事をお勧めします。

于 2012-12-15T15:41:07.873 に答える
8

サーバーコード(php)に次のヘッダーを追加することで、非常に簡単な方法で解決しました。

header('Access-Control-Allow-Origin: *');
于 2012-12-15T19:54:19.890 に答える
7

何らかの形式のJSONPメカニズムを試して実装してください。PHP を使用している場合は、次のように単純なものになる可能性があります...

/* If a callback has been supplied then prepare to parse the callback
 ** function call back to browser along with JSON. */
$jsonp = false;
if ( isset( $_GET[ 'callback' ] ) ) {
    $_GET[ 'callback' ] = strip_tags( $_GET[ 'callback' ] );
    $jsonp              = true;

    $pre  = $_GET[ 'callback' ] . '(';
    $post = ');';
} //isset( $_GET[ 'callback' ] )

/* Encode JSON, and if jsonp is true, then ouput with the callback
 ** function; if not - just output JSON. */
$json = json_encode( /* data here */ );
print( ( $jsonp ) ? $pre . $json . $post : $json );

これが行うことは、 callback$_GETという名前のvarをチェックしてから、出力を関数呼び出しでラップすることです (名前を関数名として取得します)。$_GET['callback']

次に、AJAX呼び出しは次のようになります...

$.ajax({
  type: 'GET',
  url: '/* script here */ ', 
  data: /* data here - if any */,
  contentType: "jsonp", // Pay attention to the dataType/contentType
  dataType: 'jsonp', // Pay attention to the dataType/contentType
  success: function (json) {
    /* call back */
  }
});

jQuery が'jsonp'dataType/contentType として指定されると、コールバック関数名の提供や、コールバック関数の設定などを処理します。つまり、実際に何もする必要はありません。

jQueryのドキュメントから:

"jsonp": JSONP を使用して JSON ブロックに読み込みます。「?callback=?」を追加します。URL の末尾に追加して、コールバックを指定します。キャッシュ オプションが true に設定されていない限り、クエリ文字列パラメーター "_=[TIMESTAMP]" を URL に追加してキャッシュを無効にします。

ソース

最後に; JSONP が最善の策です。サーバー側のスクリプトが PHP を使用している可能性を考慮して、PHP コードを含めました。そうでない場合、原則は同じです。ただし、サーバー側のテクノロジーに関係なく、jQuery/クライアント側のものは同じままです。(一般的に

幸運を :)

于 2012-12-15T15:52:50.397 に答える
3

ASP.NET WEB アプリケーションの場合は、これを Global.aspx に配置することもできます。

HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");

于 2012-12-15T15:54:45.887 に答える
3

その他の PHP ヘッダー設定

header('Access-Control-Allow-Origin: '.$_SERVER['HTTP_ORIGIN']);
header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
header('Access-Control-Max-Age: 1000');
header('Access-Control-Allow-Headers: Content-Type');

幸運を

于 2013-04-05T15:07:49.457 に答える