美文网首页Web前端前端开发前端研习社
最合适的Ajax内容编码类型

最合适的Ajax内容编码类型

作者: CntChen | 来源:发表于2016-09-10 17:06 被阅读83次

    最合适的Ajax内容编码类型

    原文地址:我的博客

    背景

    在公司开发的一个页面的[Ajax][Ajax]请求使用了contentType:application/json,被后台的同事要求用x-www-form-urlencoded,撕逼撕不过他,赶紧回来学学知识。

    引入

    contentType是指http/https发送信息至服务器时的内容编码类型contentType用于表明发送数据流的类型,服务器根据编码类型使用特定的解析方式,获取数据流中的数据。内容编码类型的作用,有点像本地文件的后缀名。

    问题来了

    发送Ajax请求最合适的内容编码类型是什么?

    常见的contentType

    x-www-form-urlencoded

    这是Jquery/Zepto Ajax默认的提交类型。最简例子为:

    let userInfo = {
     name: 'CntChen',
     info: 'Front-End',
    }
    
    $.ajax({
      url: 'https://github.com',
      type: 'POST',
      data: userInfo,
      success: (data) => {},
    });
    

    此时默认的提交的contentTypeapplication/x-www-form-urlencoded,此时提交的数据将会格式化成:

    name=CntChen&info=Front-End
    

    HTML的form表单默认的提交编码类型也是x-www-form-urlencoded,可能这就是Jquery/Zepto等类库(其实是Ajax:XMLHttpRequest)也默认使用contentType:x-www-form-urlencoded的原因,毕竟表单的历史比Ajax早多了。--我猜的,待验证

    如果请求类型typeGET,格式化的字符串将直接拼接在url后发送到服务端;如果请求类型是POST,格式化的字符串将放在http body的Form Data中发送。

    json

    使用json内容编码发送数据,最简例子为:

    let userInfo = {
     name: 'CntChen',
     Info: 'Front-End',
    }
    
    $.ajax({
      url: 'https://github.com',
      contentType: 'application/json',
      type: 'POST',
      data: JSON.stringify(userInfo),
      success: (data) => {},
    });
    

    最主要的不同有3点:

    • 需要显式指定contentTypeapplication/json,覆盖默认的contentType
    • 需要使用JSON.stringify序列化需要提交的数据对象,序列化的结果为:
    {"name":"CntChen","info":"Front-End"}
    
    • 提交的类型不能为GET,使用GET的话,数据会在url中发送,此时就无法以json字符串的编码发送

    multipart/form-data

    When you are writing client-side code, all you need to know is use multipart/form-data when your form includes any < input type="file" > elements.
    -- [multipart/form-data][multipart/form-data]

    multipart/form-data主要用于传输文件数据的。

    JS对象编码

    对于扁平的参数对象,使用x-www-form-urlencodedjson并没有大的差别,后台都可以处理成对象,并且数据编码后的长度差别不大。
    但是对于对象中嵌套对象,或对象字段包含数组,此时两种内容编码方式就有较大差别。

    格式化demo

    对象嵌套

    {
        userInfo :{
         name: 'CntChen',
         info: 'Front-End',
         login: true,
        },
    }
    
    • to x-www-form-urlencoded (1)
    userInfo[name]=CntChen&userInfo[info]=Front-End&userInfo[login]=true
    
    • to json (2)
    {"userInfo":{"name":"CntChen","Info":"Front-End","login":true}}
    

    对象字段为数组

    {
        authors:[
          {
            name: 'CntChen',
            info: 'Front-End',
          },
          {
            name: 'Eva',
            info: 'Banker',
          }
        ],
    }
    
    • to x-www-form-urlencoded (3)
    authors[0][name]=CntChen&authors[0][info]=Front-End&authors[1][name]=Eva&authors[1][info]=Banker
    
    • to json (4)
    {"authors":[{"name":"CntChen","info":"Front-End"},{"name":"Eva","info":"Banker"}]}
    

    可见:x-www-form-urlencoded是先将对象铺平,然后使用key=value的方式,用&作为间隔。对于嵌套对象的每个字段,都要传输其前缀,如(1)中的userInfo重复传输了3次;(3)中authors传输了4次。
    如果对象是多重嵌套的,或者嵌套对象的字段较多,x-www-form-urlencoded会产生更多冗余信息。同时,x-www-form-urlencoded可读性不如json字符串。

    回答问题:json最好

    较小的传输量

    从前文可以看出,使用json字符串的形式,可以减少冗余字段的传输,减少请求的数据量。

    补充:可能你会觉得(4)中数组内的nameinfo也传输了多次,是不是也存在冗余?其实这不是冗余。因为对数组中的各对象,并不要求其具有相同的字段(数组中的对象并不是结构化的),所以不能忽略“相同”的字段名。使用x-www-form-urlencoded编码方式,数组内对象的字段也是重复传输。

    请求与返回统一

    目前许多前后端交互的返回数据是json字符串,这可能是考虑较小的传输量而作出的选择。同时,ES3.1添加了JSON对象,许多浏览器可以[直接使用JSON对象][Can I use JSON],可以将json字符串解析为JS对象(JSON.parse),将JS对象编码为json字符串(JSON.stringify);
    所以使用json编码请求数据,其编码解码非常方便,并且可以保持与后台返回数据的格式一致。
    一致是一件很美好的事情。

    框架的支持

    目前Mvvm的前端框架如React,网络请求通常是提交一个JS对象(传输的时候编码为json字符串)。后台服务器如Koa,接收请求和响应的数据是json字符串。

    可读性高

    可读性高是json格式[自带buff][JSON]。

    结论

    赶紧使用contentType=applications/json

    References

    • Ajax

    http://css88.com/doc/zeptojs_api/#$.ajax
    [Ajax]:http://css88.com/doc/zeptojs_api/#$.ajax

    • x-www-form-urlencoded VS json - Pros and Cons. And Vulns.

    http://homakov.blogspot.in/2012/06/x-www-form-urlencoded-vs-json-pros-and.html
    [x-www-form-urlencoded VS json]:http://homakov.blogspot.in/2012/06/x-www-form-urlencoded-vs-json-pros-and.html

    • What does enctype='multipart/form-data' mean?

    http://stackoverflow.com/questions/4526273/what-does-enctype-multipart-form-data-mean
    [multipart/form-data]:http://stackoverflow.com/questions/4526273/what-does-enctype-multipart-form-data-mean

    • Can I use JSON

    http://caniuse.com/#search=JSON
    [Can I use JSON]:http://caniuse.com/#search=JSON

    • JSON

    http://www.json.org/
    [JSON]:http://www.json.org/

    END

    相关文章

      网友评论

        本文标题:最合适的Ajax内容编码类型

        本文链接:https://www.haomeiwen.com/subject/iygyettx.html