88

jQuery.ajax() を使用してサーバーから返された JSON データの解析に問題があります

私が使用しているAJAXを実行するには:

$.ajax({
  url: myUrl,
  cache: false,
  dataType: "json",
  success: function(data){
    ...
  },
  error: function(e, xhr){
    ...
  }
});  

そして、アイテムの配列を返すと、正常に動作します:

[ { title: "One", key: "1" }, { title: "Two", key: "2" } ]

成功関数が呼び出され、正しいオブジェクトを受け取ります。

ただし、単一のオブジェクトを返そうとすると:

{ title: "One", key: "1" } 

エラー関数が呼び出され、xhr に「parsererror」が含まれます。JSONをネットワークに送信する前に、サーバー上でJSONを括弧で囲んでみましたが、違いはありません。しかし、コンテンツを Javascript の文字列に貼り付けて eval() 関数を使用すると、完全に評価されます。

私が間違っていることはありますか?

アンソニー

4

20 に答える 20

72

サーバーは Content-Type としてデータを送信しています"*/json"か? そうでない場合は、それに応じて応答ヘッダーを変更します。"application/json"たとえば、送信で問題ありません。

于 2008-10-30T10:29:13.347 に答える
52

json.orgの仕様によると、あなたの返品は無効です。名前は常に引用されているので、戻ってくる必要があります

{ "title": "One", "key": "1" }

[ { "title": "One", "key": "1" }, { "title": "Two", "key": "2" } ]

これはセットアップの問題ではないかもしれませんが、そのうちの 1 つが現在機能していると言われていますが、将来別の JSON パーサーに切り替える必要がある場合に備えて、正しく修正する必要があります。

于 2008-10-30T17:45:49.157 に答える
34

JSON 文字列は二重引用符で囲みます。一重引用符は有効な代替ではありません。

{"who": "Hello World"}

は有効ですが、これはそうではありません...

{'who': 'Hello World'}

OPの問題ではありませんが、ここに着陸する他の人にとっては注目に値すると思いました.

于 2010-03-25T22:45:12.097 に答える
30

この問題は通常、リクエストが間違った MIME タイプを受け取ったために発生します。自分のコンピューターで開発する場合、自分のコンピューターである「サーバー」から適切な MIME タイプを受信しないことがあります。ブラウザでローカルに保存されたファイルを開いて開発しているときに、この問題に一度遭遇しました (たとえば、URL は「c:/project/test.html」でした)。

beforeSend プロパティを使用して、MIME タイプをオーバーライドするコールバック関数を追加してみてください。これにより、間違った MIME タイプがサーバーによって送信され、呼び出し元のコードによって受信されたにもかかわらず、コードが json を処理するようになります。いくつかのサンプルコードを以下に示します。

この質問によると、適切な MIME タイプは application/json ですが、私が試したときに application/j-son が機能したことはわかっています (現在は数年前)。最初に application/json を試す必要があります。

var jsonMimeType = "application/json;charset=UTF-8";
$.ajax({
 type: "GET",
 url: myURL,
 beforeSend: function(x) {
  if(x && x.overrideMimeType) {
   x.overrideMimeType(jsonMimeType);
  }
 },
 dataType: "json",
 success: function(data){
  // do stuff...
 }
});
于 2008-10-30T13:56:24.580 に答える
7

私はこの問題を抱えていて、少しの間使用しました

eval('('+data+')')

オブジェクトで返されたデータを取得します。しかし、その後、括弧内に 'missing )' エラーが発生するという他の問題が発生し、jQuery には json 構造の文字列を評価するための特別な関数があることがわかりました。

$.parseJSON(data)

トリックを行う必要があります。もちろん、これはjson文字列を適切な形式にすることに加えて..

于 2010-12-16T21:55:52.180 に答える
6

json 応答をエコーアウトしていて、ヘッダーが */json と一致しない場合は、組み込みの jQuery.parseJSON API を使用して応答を解析できます。

response = '{"name":"John"}';
var obj = jQuery.parseJSON(response);
alert( obj.name === "John" );
于 2012-05-16T22:44:00.377 に答える
4
{ title: "One", key: "1" }

あなたが考えるものではありません。式としては Object リテラルですが、ステートメントとしては次のようになります。

{                // new block
    title:       // define a label called 'title' for goto statements
        "One",   // statement: the start of an expression which will be ignored
        key:     // ...er, what? you can't have a goto label in the middle of an expression
                 // ERROR

残念ながら、 eval() は、ステートメントまたは式のどちらを指定するかを指定する方法を提供せず、間違った推測をする傾向があります。

通常の解決策は、eval() 関数に送信する前に何かを括弧で囲むことです。あなたはサーバーでそれを試したと言います...明らかにどういうわけかそれはうまくいきません。XMLHttpRequest 応答を受信するものは何でも、クライアント側で言うのは防水でなければなりません:

eval('('+responseText+')');

それ以外の:

eval(responseText);

応答が実際にステートメントではなく式である限り。(たとえば、セミコロンまたは改行で区切られた複数の句はありません。)

于 2008-10-30T14:24:38.003 に答える
3

次のように、php でヘッダーのコンテンツ タイプを設定する必要があります。

 <?php

 header('Content-type:application/json');

 ?>

理解を深めるために、これらのビデオをご覧ください。

参照: http://www.youtube.com/watch?v=EvFXWqEqh6o

于 2014-07-27T04:59:34.467 に答える
2

これと同様の問題があり、Firefox 3.5 は正常に動作し、JSON データを解析しましたが、Firefox 3.0.6 は解析エラーを返しました。Firefox 3.0.6 がエラーをスローする原因となったのは、JSON の先頭にある空白であることが判明しました。空白を削除すると修正されました

于 2010-01-27T11:52:03.053 に答える
2

jQuery を使用して ASP.NET Web サービスを使用している場合は、web.config に次のものが含まれていることを確認してください。

<webServices>
    <protocols>
        <add name="HttpGet"/>
        <add name="HttpPost"/>
    </protocols>
</webServices>
于 2008-12-08T21:05:25.097 に答える
2

テクニック「eval()」と「JSON.parse()」は、相互に排他的な形式を使用します。

  • 「eval()」では括弧が必要です
  • 「JSON.parse()」では括弧は禁止されています。

「eval」形式を生成する「stringify()」関数があることに注意してください。ajax の場合は、JSON 形式のみを使用する必要があります。

「eval」には JavaScript 言語全体が組み込まれていますが、JSON は言語の小さなサブセットのみを使用します。「eval」が認識しなければならない JavaScript 言語の構成要素には、「ブロック ステートメント」(別名「複合ステートメント」)があります。これはペアまたは中括弧 "{}" で、内部にいくつかのステートメントがあります。ただし、中括弧はオブジェクト リテラルの構文でも使用されます。解釈は、コードが表示されるコンテキストによって区別されます。何かがオブジェクト リテラルのように見えるかもしれませんが、「eval」はそれを複合ステートメントと見なします。

JavaScript 言語では、オブジェクト リテラルは代入の右側にあります。

var myObj = { ...some..code..here... };

オブジェクト リテラルは単独では発生しません。

{ ...some..code..here... }   // this looks like a compound statement

2008年に尋ねられたOPの元の質問に戻り、彼は「eval()」で以下が失敗する理由を尋ねました。

{ title: "One", key: "1" }

答えは、複合ステートメントのように見えるということです。オブジェクトに変換するには、複合ステートメントが不可能なコンテキストに配置する必要があります。これは、括弧を付けることによって行われます

( { title: "One", key: "1" } )    // not a compound statment, so must be object literal

OP は、同様のステートメントが正常に評価された理由も尋ねました。

[ { title: "One", key: "1" }, { title: "Two", key: "2" } ]

同じ答えが当てはまります。中括弧は、複合ステートメントが不可能なコンテキストにあります。これは配列コンテキスト " [...]" であり、配列にはオブジェクトを含めることができますが、ステートメントを含めることはできません。

「eval()」とは異なり、JSON はその機能が非常に制限されています。制限は意図的なものです。JSON の設計者は、割り当ての右側に表示できる構文のみを使用して、JavaScript の最小限のサブセットを意図していました。したがって、JSON で正しく解析するコードがあれば...

var myVar = JSON.parse("...some...code...here...");

...これは、このように、割り当ての右側でも合法的に解析されることを意味します..

var myVar = ...some..code..here... ;

しかし、JSON の制限はそれだけではありません。JSONのBNF 言語仕様は非常に単純です。たとえば、単一引用符を使用して文字列を示すことはできません (JavaScript や Perl のように)。また、単一の文字をバイトとして表現する方法もありません ('C' のように)。残念ながら、コメントも許可されていません (構成ファイルを作成するときに非常に便利です)。これらすべての制限の利点は、JSON の解析が高速であり、コード インジェクション (セキュリティの脅威) の機会がないことです。

これらの制限により、JSON では括弧は使用されません。したがって、JSON 文字列内の括弧は不正な文字です。

次の理由により、ajax では常に JSON 形式を使用します。

  • 典型的な ajax パイプラインは、JSON 用に構成されます。
  • 「eval()」の使用は、セキュリティ リスクとして批判されます。

ajax パイプラインの例として、ノード サーバーと jQuery クライアントを含むプログラムを考えてみましょう。クライアント プログラムは、フォームを持つ jQuery 呼び出しを使用します$.ajax({dataType:'json',...etc.});。JQuery は、後で使用するために jqXHR オブジェクトを作成し、関連する要求をパッケージ化して送信します。サーバーは要求を受け入れて処理し、応答する準備が整います。サーバー プログラムはメソッドres.json(data)を呼び出してパッケージ化し、応答を送信します。クライアント側に戻ると、jQuery は応答を受け取り、関連する jqXHR オブジェクトを調べて、JSON 形式のデータを処理します。これはすべて、手動のデータ変換を必要とせずに機能します。応答には、Node サーバーでの JSON.stringify() への明示的な呼び出しは含まれず、クライアントでの JSON.parse() への明示的な呼び出しも含まれません。それはすべてあなたのために処理されます。

「eval」の使用には、コード インジェクションのセキュリティ リスクが伴います。そんなことはあり得ないと思うかもしれませんが、ハッカーは非常に創造的になることができます。また、「eval」は Javascript の最適化に問題があります。

「stringify()」関数を使用している場合は、その名前の一部の関数が、JSON ではなく「eval」と互換性のある文字列を作成することに注意してください。たとえば、Node では、「eval」互換形式で文字列を作成する関数を次のように指定します。

var stringify = require('node-stringify'); // generates eval() format

これは便利かもしれませんが、特別な必要がない限り、おそらくあなたが望むものではありません。

于 2016-11-13T00:14:53.393 に答える
1

これも試してみてください

$.ajax({
    url: url,
    data:datas,
    success:function(datas, textStatus, jqXHR){
    var returnedData = jQuery.parseJSON(datas.substr(datas.indexOf('{')));
})};

私の場合、サーバーは「{」の前に不明な文字で応答します

于 2012-04-06T13:22:56.803 に答える
1

jQuery のエラー ハンドラーが呼び出され、XHR オブジェクトに「パーサー エラー」が含まれている場合、それはおそらくサーバーから返されたパーサー エラーです。

パラメータなしでサービスを呼び出したときの複数の結果のシナリオはありますが、単一のレコードを取得するためにパラメータを指定しようとすると壊れますか?

どのバックエンドからこれを返していますか?

たとえば、ASMX サービスでは、パラメーターが JSON 文字列ではなく JSON オブジェクトとして jQuery に提供される場合がよくあります。jQuery にその「データ」パラメーターに実際の JSON オブジェクトを提供すると、JSON として送信する代わりに、それを標準 & 区切り k,v ペアにシリアル化します。

于 2008-11-28T04:48:05.977 に答える
1

ColdFusion 環境でエラーが発生する原因の 1 つは、整形式の JSON であっても、ColdFusion Administrator ([デバッグとログ] > [デバッグ出力設定] の下) で [リクエストのデバッグ出力を有効にする] をオンにしている場合です。デバッグ情報は JSON データと共に返されるため、無効になります。

于 2011-04-04T17:40:16.197 に答える
1

jQuery は、特定の JSON キーでチョークします。PHP で次の JSON スニペットを送信していました。

echo json_encode((object) array('result' => 'success'));

「結果」キーの名前を別のものに変更すると機能します。これはある種の予約語の衝突であり、jQuery (1.4.2) のバグである可能性があると思います。

于 2011-01-07T23:34:30.673 に答える
1

私が追加しなければならなかった私の実装のいくつかで見つけました:

obj = new Object; obj = (data.obj);

問題を解決するように見えました。Eval であろうとなかろうと、私にとってはまったく同じように見えました。

于 2008-11-29T16:01:01.050 に答える
1

配列を返すことが機能し、単一のオブジェクトを返すことが機能しない場合は、単一のオブジェクトをその単一のオブジェクトを含む配列として返すこともできます。

[ { title: "One", key: "1" } ]

そうすれば、データ ペイロードに関係なく、一貫したデータ構造、オブジェクトの配列を返すことができます。

単一のオブジェクトを「括弧」でラップしようとしたことがわかります。もちろん、JavaScript は [ .. ] を ( .. ) とは異なる方法で処理するため、これを例で提案します。

于 2008-10-30T14:17:19.937 に答える
0

私はこれに苦労しており、firebug を使用してデータ オブジェクトを表示するまで、これを理解しようと数時間を費やしました。

var data = eval("(" + data.responseText + ")");
console.log(data.count);
于 2011-04-29T23:50:45.950 に答える
-1

使用する

$data = yourarray(); 
json_encode($data)

サーバー側で。クライアント側では、Datatype JSON で ajax を使用し、ドキュメントのエンコーディングが UTF-8 である必要がある BOM で UTF-8 でないことを確認してください。

于 2014-07-22T10:53:11.630 に答える