web-dev-qa-db-ja.com

jQuery getJSONはローカルで機能しますが、クロスドメインでは機能しません

私はFOREVERを検索しましたが、私の問題に対する明確な答えを見つけることができません。だからここにあります。次のようなJSONファイルがあります(検証するためにjsonlintに行って、それは良いと言っています)(一部の情報は変更されています)。

[{
        "position":"1",
        "category":"A",
        "title":"Title to first story",
        "description":"The first story."
    },
    {
        "position":"2",
        "category":"B",
        "title":"Title to second story",
        "description":"The second story"
    },
    {
        "position":"3",
        "category":"B",
        "title":"Title to third story",
        "description":"The third story"
    }
]

私はjQueryを使用して解析し、この関数を使用してHTMLページに配置しました。

$.getJSON('page.json', function(data) {
  var items = [];

  $.each(data.reponse, function(item, i) {
    items.Push('<li id="' + i.position + '">' + i.title + ' - ' + i.description + '</li>');
  });

  $('<ul/>', {
    'class': 'my-new-list',
    html: items.join('')
  }).appendTo('body');
});

それは完全に動作します!ここで私の問題が出てきます。JSONファイルはローカルでホストされず、実際には別のドメインでホストされます。それで、私はコードを次のように変更して(ある程度読んだ後)、それが機能することを期待しています:

$.getJSON('http://www.otherdomain.com/page.json?format=json&callback=?', function(data) {
  var items = [];

  $.each(data.reponse, function(item, i) {
    items.Push('<li id="' + i.position + '">' + i.title + ' - ' + i.description + '</li>');
  });

  $('<ul/>', {
    'class': 'my-new-list',
    html: items.join('')
  }).appendTo('body');
});

「コールバック」行を追加することにより、「リソースのロードに失敗しました」エラーの発生を停止しました。しかし、何も起こっていません。追加した機能がないみたいです。私はそれをすべて取り除いて、単純な「alert(data)」を追加しようとしましたが、それでも起動しませんでした。何が悪いのですか?大きな問題は、私が動作するHTMLとJavaScriptだけに100%制限されていることです(私の選択ではありません)。助けてくれてありがとう!

[〜#〜] edit [〜#〜]わかりました。他のサーバーがjsonファイルに動的に何かを追加する機能はありません。そこで、json(小さいサンプル)の周りに関数をハードコーディングして変更しました。

storyData(
[{
        "position":"1",
        "category":"A",
        "title":"Title to first story",
        "description":"The first story."
    }
])

すべてがうまくいきました!助けてくれてありがとう!

12
Dusty

[〜#〜] jsonp [〜#〜] を調べる必要があります。

基本的に、別のドメインからJSONをロードしようとすると、通過できないドメイン境界があるため失敗します。これを回避するには、[〜#〜] pad [〜#〜]する必要があります(JSONPのP)。パディングとは、基本的には関数呼び出しで関数をラップすることです(関数名はクライアント上にあります)。 「通常の」JSON応答(たとえば、getjson.php):

{foo:'bar'}

parseJSONのコールバックを持つJSONは次のようになります(たとえば、getjson.php?callback = parseJSON):

parseJSON({foo:'bar'})

callbackで提供された値が、JSON応答がラップされる関数の名前になる方法に注意してください。

次に、クライアントはそれをparseJSON、つまりクライアント上に存在する関数(定義済み)に渡します。 jQuery(およびその他のライブラリ)は、「ランダム」関数を生成し、元のコールバックを介して応答を送信することにより、これを処理しようとします(これはすべて内部で行われます)。

JSONを生成するサーバーページを制御できる場合は、コールバックメソッドを実装して、JSONをラップする方法を指定して、JSONを自分の側で操作できるようにします。 (これは、クライアントが現在存在しているページ以外のドメインからのデータを処理する場合にのみ必要です)。


更新

基本的に、発生している問題を解決するには、JSON情報をJSONP呼び出しに取り込む方法を見つける必要があります。 「page.json」の言語がわからない場合は、次の疑似コードロジックに含める必要があります。

if GET_VARIABLE("callback") is supplied

  print GET_VARIABLE("callback") and an open parenthesis
  print normal JSON data
  print closing parenthesis

else

  print normal JSON data

end if

関数名を "コールバック"としてURLに提供するのではなく、関数名をハードコーディングする場合は、覚えておく必要があります。次の例では、名前を付けたとしましょうMyJSONPCallback

これで、クライアントコードで、使用を先に進めることができます。

$.ajax({
  url: 'http://anotherdomain.com/page.json?format=json',
  dataType: 'json',
  jsonpCallback: 'MyJSONPCallback', // specify the callback name if you're hard-coding it
  success: function(data){
    // we make a successful JSONP call!
  }
});
15
Brad Christie

MVC ActionResultを使用してJSONPを生成する場合、ASP.NET MVCにはJSONPサポートが付属していませんが、次のように簡単に追加できます。

http://nikcodes.com/2012/02/29/an-asp-net-mvc-jsonp-actionresult

2
arpad

ブラウザは、これをセキュリティ対策として機能させません。これを回避する方法としてJSONPをチェックアウトすることもできますが、JSONテキストの取得元のドメインによって提供されるJavaScriptの実行に依存しているため、セキュリティリスクが非常に高くなります。

0
psr

私はこの問題を詳しく調べていませんが、あなたの問題は同じドメインポリシーに関連していると思います...しかし、これを調べたいと思うかもしれません: http://james.padolsey.com/javascript/ cross-domain-requests-with-jquery /

0
CenterOrbit

Brad Christieの回答は、コードをすばやく機能させるのに役立ちました。他のソリューションよりも簡単なので、ここに新しいエントリを作成しています。

以下は、私が実行するコードです http:// localhost:50 -

(function() {
        var api = "http://www.localhost:3000/auget_from_server?format=json";
        var request = $.getJSON( api, {
            secret : 'secret', 
            appId : 'app', 
            emailId : '[email protected]',
            async: false,
            dataType : 'json',
          },
          function(data, result){
            $("div.some_div").append(JSON.stringify(data));
          });

        request.complete(function(d, status){
            console.log('Complete the request and got the data - ' + JSON.stringify(d) + '/' + status, filename);
        });

        request.error(function(err){
            console.log('Error happened - ', filename);
            console.log(err);
        });

        request.success(function( data, status, jqXHR ) {
            $("div.some_div").append(data);
        });


        })();

http:// localhost:3000/auget_from_server の場所から、応答として次のJSONを返します(この部分は流星に固有ですが、流星以外のサーバーでも機能します)-

this.response.writeHead('200', {'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*'});
this.response.end(JSON.stringify([{'works_or_not' : 'works', 'name' : 'akaushik', 'application' : 'Qoll', 'message' : 'hello from server', 'currentTime' : dt+''}]));

これはログに以下を出力します-

Complete the request and got the data - {"readyState":4,"responseText":"[{\"works_or_not\":\"works\",\"name\":\"akaushik\",\"application\":\"Qoll\",\"message\":\"hello from server\",\"currentTime\":\"Tue Dec 15 2015 23:59:14 GMT-0500 (EST)\"}]","responseJSON":[{"works_or_not":"works","name":"akaushik","application":"Qoll","message":"hello from server","currentTime":"Tue Dec 15 2015 23:59:14 GMT-0500 (EST)"}],"status":200,"statusText":"OK"}/success
0
procrazium

この記事を参照してください-関数にラップされた有効なJavaScriptオブジェクトを提供する必要があります。

http://en.wikipedia.org/wiki/JSONP

あなたは次のようなものを返したいでしょう:

parseResponse({"Name": "Cheeso", "Id" : 1823, "Rank": 7})

しかし、サーバー側のメソッドは、JSONだけを返すのではなく、それを返すように知っている必要があります。 jQueryが行うのは、関数名(?callbackパラメータで)、サーバーから返された「関数」を評価します。サーバーは、内部に含まれるJSONを使用して関数呼び出しを作成します。

0
David Hoerster