jQuery 不会从 AJAX 查询解析我的 JSON

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/249692/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 08:50:00  来源:igfitidea点击:

jQuery won't parse my JSON from AJAX query

jqueryajaxjson

提问by littlecharva

I'm having difficulty parsing some JSON data returned from my server using jQuery.ajax()

我在使用 jQuery.ajax() 解析从我的服务器返回的一些 JSON 数据时遇到了困难

To perform the AJAX I'm using:

要执行我正在使用的 AJAX:

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

And if I return an array of items then it works fine:

如果我返回一组项目,那么它工作正常:

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

The success function is called and receives the correct object.

成功函数被调用并接收正确的对象。

However, when I'm trying to return a single object:

但是,当我尝试返回单个对象时:

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

The error function is called and xhr contains 'parsererror'. I've tried wrapping the JSON in parenthesis on the server before sending it down the wire, but it makes no difference. Yet if I paste the content into a string in Javascript and then use the eval() function, it evaluates it perfectly.

错误函数被调用,xhr 包含'parsererror'。我已经尝试将 JSON 包装在服务器上的括号中,然后再将其发送到网络上,但这没有区别。然而,如果我将内容粘贴到 Javascript 中的字符串中,然后使用 eval() 函数,它会完美地评估它。

Any ideas what I'm doing wrong?

任何想法我做错了什么?

Anthony

安东尼

采纳答案by Tomalak

Is your server sending data as Content-Type "*/json"? If not, modify the response headers accordingly. Sending "application/json"would be fine, for example.

您的服务器是否将数据作为 Content-Type 发送"*/json"?如果没有,请相应地修改响应标头。"application/json"例如,发送就可以了。

回答by Ben Combee

According to the json.orgspecification, your return is invalid. The names are always quoted, so you should be returning

根据json.org规范,您的退货无效。名字总是被引用,所以你应该回来

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

and

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

This may not be the problem with your setup, since you say one of them works now, but it should be fixed for correctness in case you need to switch to another JSON parser in the future.

这可能不是您的设置的问题,因为您说其中一个现在可以工作,但应该修复它以确保正确性,以防您将来需要切换到另一个 JSON 解析器。

回答by John Mee

JSON strings are wrapped in doublequotes; single quotes are not a valid substitute.

JSON 字符串用引号括起来;单引号不是有效的替代品。

{"who": "Hello World"}

is valid but this is not...

是有效的,但这不是......

{'who': 'Hello World'}

Whilst not the OP's issue, thought it worth noting for others who land here.

虽然不是 OP 的问题,但认为对于登陆这里的其他人来说值得注意。

回答by Josh

This problem is usually because your request received the wrong mime type. When developing on your own computer, sometimes you are not receiving the proper mime type from the "server", which is your own computer. I ran into this problem once when developing by opening the locally stored file in the browser (e.g. the url was "c:/project/test.html").

这个问题通常是因为您的请求收到了错误的 MIME 类型。在您自己的计算机上进行开发时,有时您没有从“服务器”(即您自己的计算机)接收到正确的 MIME 类型。通过在浏览器中打开本地存储的文件进行开发时,我遇到了这个问题(例如,url 是“c:/project/test.html”)。

Try using the beforeSend property to add a callback function that overrides the mime type. This will trick the code into dealing with json despite the wrong mime type being sent by the server and received by your calling code. Some example code is below.

尝试使用 beforeSend 属性添加覆盖 mime 类型的回调函数。尽管服务器发送了错误的 mime 类型并由您的调用代码接收,但这将诱使代码处理 json。一些示例代码如下。

The proper mime type is application/json according to this question, but I do know that application/j-son worked when I tried it (now several years ago). You should probably try application/json first.

根据这个问题,正确的 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...
 }
});

回答by Jubair

I had this issue and for a bit I used

我有这个问题,我使用了一段时间

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

to get the data returned in an object. but then later had other issues getting a 'missing ) in parenthetical' error and found out that jQuery has a function specifically for evaluating a string for a json structure:

获取对象中返回的数据。但是后来遇到了其他问题,在括号中出现了“缺失)”错误,并发现 jQuery 有一个专门用于评估 json 结构字符串的函数:

$.parseJSON(data)

should do the trick. This is in addition to having your json string in the proper format of course..

应该做的伎俩。当然,这也是让您的 json 字符串采用正确格式的补充。

回答by Nezzy

If you are echoing out the json response and your headers don't match */json then you can use the built in jQuery.parseJSON api to parse the response.

如果您要回显 json 响应并且您的标头与 */json 不匹配,那么您可以使用内置的 jQuery.parseJSON api 来解析响应。

response = '{"name":"John"}';
var obj = jQuery.parseJSON(response);
alert( obj.name === "John" );

回答by bobince

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

Is not what you think. As an expression, it's an Object literal, but as a statement, it's:

不是你想的那样。作为一个表达式,它是一个对象字面量,但作为一个语句,它是:

{                // 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

Unfortunately eval() does not give you a way to specify whether you are giving it a statement or an expression, and it tends to guess wrong.

不幸的是 eval() 没有给你一个方法来指定你是给它一个语句还是一个表达式,它往往会猜错。

The usual solution is indeed to wrap anythingin parentheses before sending it to the eval() function. You say you've tried that on the server... clearly somehow that isn't getting through. It should be waterproof to say on the client end, whatever is receiving the XMLHttpRequest response:

通常的解决方案确实是在将任何内容发送到 eval() 函数之前将其包装在括号中。你说你已经在服务器上尝试过……显然以某种方式没有通过。无论接收到 XMLHttpRequest 响应,客户端都应该是防水的:

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

instead of:

代替:

eval(responseText);

as long as the response is really an expression not a statement. (eg. it doesn't have multiple, semicolon-or-newline-separated clauses.)

只要响应确实是一个表达式而不是一个语句。(例如,它没有多个分号或换行符分隔的子句。)

回答by user3612872

You will to have to set header content type in your php like this:

您必须像这样在 php 中设置标题内容类型:

 <?php

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

 ?>

Watch these Video for better understanding....

观看这些视频以更好地理解....

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

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

回答by IAM_AL_X

The techniques "eval()" and "JSON.parse()" use mutually exclusive formats.

技术“eval()”和“JSON.parse()”使用互斥格式。

  • With "eval()" parenthesis are required.
  • With "JSON.parse()" parenthesis are forbidden.
  • 随着“的eval()”括号是必需的
  • 禁止使用“JSON.parse()”括号。

Beware, there are "stringify()" functions that produce "eval" format. For ajax, you should use only the JSON format.

请注意,有产生“eval”格式的“stringify()”函数。对于 ajax,您应该只使用 JSON 格式。

While "eval" incorporates the entire JavaScript language, JSON uses only a tiny subset of the language. Among the constructs in the JavaScript language that "eval" must recognize is the "Block statement" (a.k.a. "compound statement"); which is a pair or curly braces "{}" with some statements inside. But curly braces are also used in the syntax of object literals. The interpretation is differentiated by the context in which the code appears. Something might look like an object literal to you, but "eval" will see it as a compound statement.

虽然“eval”包含了整个 JavaScript 语言,但 JSON 只使用了该语言的一小部分。在 JavaScript 语言中,“eval”必须识别的结构是“Block statement”(又名“复合语句”);这是一对或大括号“{}”,里面有一些语句。但是花括号也用于对象字面量的语法中。解释因代码出现的上下文而异。有些东西对你来说可能看起来像一个对象字面量,但“eval”会把它看作是一个复合语句。

In the JavaScript language, object literals occur to the right of an assignment.

在 JavaScript 语言中,对象文字出现在赋值的右侧。

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

Object literals don't occur on their own.

对象文字不会单独出现。

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

Going back to the OP's original question, asked in 2008, he inquired why the following fails in "eval()":

回到 2008 年 OP 的原始问题,他询问了为什么“eval()”中出现以下问题:

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

The answer is that it looks like a compound statement. To convert it into an object, you must put it into a context where a compound statement is impossible. That is done by putting parenthesis around it

答案是它看起来像一个复合语句。要将其转换为对象,您必须将其放入无法使用复合语句的上下文中。这是通过在它周围加上括号来完成的

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

The OP also asked why a similar statement didsuccessfully eval:

OP 还询问为什么类似的语句确实成功 eval:

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

The same answer applies -- the curly braces are in a context where a compound statement is impossible. This is an array context, "[...]", and arrays can contain objects, but they cannot contain statements.

同样的答案也适用——花括号在不可能使用复合语句的上下文中。这是一个数组上下文,“ [...]”,数组可以包含对象,但不能包含语句。

Unlike "eval()", JSON is very limited in its capabilities. The limitation is intentional. The designer of JSON intended a minimalist subset of JavaScript, using only syntax that could appear on the right hand side of an assignment. So if you have some code that correctly parses in JSON...

与“eval()”不同,JSON 的功能非常有限。限制是有意的。JSON 的设计者打算使用 JavaScript 的极简子集,只使用可能出现在赋值右侧的语法。因此,如果您有一些可以在 JSON 中正确解析的代码......

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

...that implies it will also legally parse on the right hand side of an assignment, like this..

...这意味着它也将合法地在赋值的右侧进行解析,就像这样..

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

But that is not the only restriction on JSON. The BNF language specification for JSONis very simple. For example, it does not allow for the use of single quotes to indicate strings (like JavaScript and Perl do) and it does not have a way to express a single character as a byte (like 'C' does). Unfortunately, it also does not allow comments (which would be really nice when creating configuration files). The upside of all those limitations is that parsing JSON is fast and offers no opportunity for code injection (a security threat).

但这并不是对 JSON 的唯一限制。JSONBNF 语言规范非常简单。例如,它不允许使用单引号来表示字符串(如 JavaScript 和 Perl 所做的那样),并且它无法将单个字符表示为字节(如 'C' 那样)。不幸的是,它也不允许注释(这在创建配置文件时会非常好)。所有这些限制的好处是解析 JSON 速度很快,并且不会提供代码注入的机会(一种安全威胁)。

Because of these limitations, JSON has no use for parenthesis. Consequently, a parenthesis in a JSON string is an illegal character.

由于这些限制,JSON 没有使用括号。因此,JSON 字符串中的括号是非法字符。

Always use JSON format with ajax, for the following reasons:

始终在 ajax 中使用 JSON 格式,原因如下:

  • A typical ajax pipeline will be configured for JSON.
  • The use of "eval()" will be criticised as a security risk.
  • 将为 JSON 配置典型的 ajax 管道。
  • 使用“eval()”将被批评为存在安全风险。

As an example of an ajax pipeline, consider a program that involves a Node server and a jQuery client. The client program uses a jQuery call having the form $.ajax({dataType:'json',...etc.});. JQuery creates a jqXHR object for later use, then packages and sends the associated request. The server accepts the request, processes it, and then is ready to respond. The server program will call the method res.json(data)to package and send the response. Back at the client side, jQuery accepts the response, consults the associated jqXHR object, and processes the JSON formatted data. This all works without any need for manual data conversion. The response involves no explicit call to JSON.stringify() on the Node server, and no explicit call to JSON.parse() on the client; that's all handled for you.

作为 ajax 管道的一个例子,考虑一个包含 Node 服务器和 jQuery 客户端的程序。客户端程序使用 jQuery 调用,其形式为$.ajax({dataType:'json',...etc.});. jQuery 创建一个 jqXHR 对象供以后使用,然后打包并发送关联的请求。服务器接受请求,处理它,然后准备响应。服务器程序将调用该方法res.json(data)打包并发送响应。回到客户端,jQuery 接受响应,查询关联的 jqXHR 对象,并处理 JSON 格式的数据。这一切都无需手动数据转换即可工作。响应不涉及在 Node 服务器上显式调用 JSON.stringify(),也不涉及在客户端显式调用 JSON.parse();这一切都为你处理。

The use of "eval" is associated with code injection security risks. You might think there is no way that can happen, but hackers can get quite creative. Also, "eval" is problematic for Javascript optimization.

“eval”的使用与代码注入安全风险有关。您可能认为这不可能发生,但黑客可以变得非常有创意。此外,“eval”对于 Javascript 优化也是有问题的。

If you do find yourself using a using a "stringify()" function, be aware that some functions with that name will create strings that are compatible with "eval" and not with JSON. For example, in Node, the following gives you function that creates strings in "eval" compatible format:

如果您确实发现自己使用了“stringify()”函数,请注意某些具有该名称的函数将创建与“eval”兼容的字符串,而不是与 JSON 兼容的字符串。例如,在 Node 中,下面给出了以“eval”兼容格式创建字符串的函数:

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

This can be useful, but unless you have a specific need, it's probably not what you want.

这可能很有用,但除非您有特定需求,否则它可能不是您想要的。

回答by Andreas Grech

If you are consuming ASP.NET Web Services using jQuery, make sure you have the following included in your web.config:

如果您使用 jQuery 使用 ASP.NET Web 服务,请确保您的 web.config 中包含以下内容:

<webServices>
    <protocols>
        <add name="HttpGet"/>
        <add name="HttpPost"/>
    </protocols>
</webServices>