简体   繁体   English

通过AJAX发送JSON时的奇怪行为

[英]Strange behavior when sending JSON over AJAX

I am encountering some really strange behavior when sending JSON over AJAX. 通过AJAX发送JSON时遇到一些非常奇怪的行为。

JSON data: JSON数据:

data = {
    "name": "box1",
    "comment": ["fragile"],
    "type_A": [
        {
            "item": "1",
            "attr": [
                "big",
                "red"
            ]
        },
        {
            "item": "2",
            "attr": [
                "small",
                "red"
            ]
        },
    ],
    "type_B": [],
    "misc": {}
};

POST request: POST请求:

$.ajax({
    url: url,
    type: "POST",
    // data: JSON.stringify(data),
    data: data,
    success: function (result) {
        console.log("inside success");
    },
    error: function (error) {
        console.log("inside error");
    }
});

If I pass in data here without JSON.stringify() , the empty fields type_B and misc get lost/stripped away. 如果我在此处不使用JSON.stringify()传递data ,则空字段type_Bmisc会丢失/丢失。 But if I do use JSON.stringify() then the backend cannot parse it properly without JSON.parse() . 但是,如果我确实使用JSON.stringify()那么如果没有JSON.parse() ,后端将无法正确解析它。 Is there a way to not strip away empty fields without doing a JSON.parse() in the backend? 有没有一种方法可以在后台不进行JSON.parse()情况下去除空字段?

I tried adding contentType: "application/json" and dataType: "json" to the request but didn't help. 我尝试向请求添加contentType: "application/json"dataType: "json" ,但没有帮助。

What you have labeled "JSON data" is not JSON. 您标记为“ JSON数据”的不是JSON。 It is a JavaScript object literal. 它是一个JavaScript对象文字。 It is part of JavaScript source code. 它是JavaScript源代码的一部分。 It is not a JSON data file. 它不是JSON数据文件。

When you use jQuery's Ajax functions you can pass a few different things to data . 使用jQuery的Ajax函数时,您可以将一些不同的东西传递给data

If you pass it an object, then jQuery will Form URL Encode it. 如果将对象传递给它,则jQuery将对它进行URL编码。

URL Encoded data has no standard way to represent anything other than a set of flat key=value pairs. 除一组平面键=值对之外,URL编码数据没有标准方法来表示任何其他内容。

PHP introduced an extension which lets you express arrays and associative arrays by using square brackets in the key names. PHP引入了一个扩展,使您可以通过在键名中使用方括号来表示数组和关联数组。 For example: 例如:

array[]=item1&array[]=item2

Each items in the array is represented by a copy of the key. 数组中的每个项目都由键的副本表示。

If you have no items, then there are no keys of that name. 如果没有项目,则没有该名称的键。

If you use this method of encoding data then you cannot express empty arrays. 如果使用这种编码数据的方法,则无法表达空数组。 The closest you could come would be to have an array containing a zero length string. 最接近的可能是包含长度为零的字符串的数组。

If you pass it a string, then jQuery will just send it as is. 如果您将其传递给字符串,那么jQuery只会按原样发送它。

Using JSON.stringify will convert your object to a string containing JSON data. 使用JSON.stringify会将您的对象转换为包含JSON数据的字符串。

JSON is capable of expressing empty arrays. JSON能够表达空数组。

PHP, however, will not automatically parse JSON formatted requests. 但是,PHP不会自动解析JSON格式的请求。

So… 所以…

Is there a way to not strip away empty fields without doing a JSON.parse() in the backend? 有没有一种方法可以在后台不进行JSON.parse()的情况下去除空字段?

No. There isn't. 不,没有。 You either use a format which doesn't support empty fields, or you use a format which PHP won't automatically parse for you. 您要么使用了不支持空字段的格式,要么使用了PHP不会自动为您解析的格式。

I tried adding contentType: "application/json" 我尝试添加contentType:“ application / json”

This tells the server that the data you are sending is encoded as JSON. 这告诉服务器您正在发送的数据被编码为JSON。 If you are sending JSON then you should include this. 如果要发送JSON,则应包含此内容。

It doesn't alter the data you send. 它不会改变您发送的数据。 You need to encode the data as JSON yourself. 您需要自己将数据编码为JSON。

and dataType: "json" to the request but didn't help. 和dataType:“ json”到请求,但没有帮助。

This tells the server that you expect the response to the request to contain JSON. 这告诉服务器,您希望对请求的响应包含JSON。 It also tells jQuery to ignore the content-type of the response and parse it as JSON whatever the server says it is. 它还告诉jQuery忽略响应的内容类型,并将其解析为JSON(无论服务器说的是什么)。

It has no effect on the data you send. 它对您发送的数据没有影响。

Jquery processes your data before sending and uses the request's post formdata instead of putting JSON in the body of the request. jQuery在发送之前处理您的数据,并使用请求的post formdata而不是将JSON放入请求的主体中。

To avoid this, use processData: false and contentType: 'application/json' : 为了避免这种情况,请使用processData: falsecontentType: 'application/json'

$.ajax({
    url: url,
    type: "POST",
    processData: false,
    contentType: 'application/json',
    data: JSON.stringify(data),
    success: function (result) {
        console.log("inside success");
    },
    error: function (error) {
        console.log("inside error");
    }
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM