zoukankan      html  css  js  c++  java
  • 前后端联调编码格式探究

    前后端联调的时候经常要约定数据交互的编码格式;这里我们所说的编码格式即是————HTTP请求头部的属性Content-Type。

    更多解释还请看MDN:Content-Type

    content-type 作为文件的编码类型有很多种,在前后端的交互中,请求头与返回(响应)头都有;
    这些头里面的 content-type 可以由前端、后端程序员控制;
    这里我主要想了解一下前端发送请求时的请求头的 content-type:

    • application/json
    • application/x-www-form-urlencoded
    • multipart/form-data

    其他常见的页面资源类型:text/html, text/plain, text/css, text/javascript, image/jpeg, image/png, image/gif


    application/json

    当我们使用这种格式的时候,浏览器会将这种数据格式放在 Request Payload 这个载体中。

    • 格式案例

      {"name":"","psd":""}
      
    • Chrome浏览器的 Request Payload 中可以看到我们所传输的数据,形式案例如下:

    • axios传输注意,传输这种格式的时候只要将 header 的配置写对,基本就不会有太大问题,案例代码:

      this.$api.post('/prefix/postBody', params, {
        headers: {
          'Content-Type': 'application/json'
        }
      }).then(res => {
        console.log('res', res)
      })
      

    application/x-www-form-urlencoded

    当我们使用这种格式的时候,浏览器会将这种数据格式放在 Form Data 这个载体中。

    • 格式案例
      test=1&a=2&b=3
      
    • Chrome浏览器的 Form Data 中可以看到我们所传输的数据,形式案例如下:

      (这里与我们上方格式不同是因为Chrome浏览器为了方便我们观测,作了解析)

    • axios传输注意,传输这种格式的时候除了将 header 的配置写对,传输数据类型的格式也要写好(注意了,不能直接使用 JSON.stringify 来进行序列化;因为它的stringify并不能达到将obj对象数据转化为"test=1&a=2&b=3"的类型,通常我们使用qs库的stringify函数):
      const params = qs.stringify({ test: 1, a: 2, b: 3 })
      this.$api.post('/prefix/postBody', params, {
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
        }
      }).then(res => {
        console.log('res', res)
      })
      

    multipart/form-data

    • 格式案例:
      参照网上的博客,它可能是多种数据合并起来的,所以并非有统一的格式;我们可以规定字符(boundary)来确定他们的分隔符号是什么。
      参考微软小哥的博客
    • Chrome浏览器的 Form Data 中可以看到我们所传输的数据,形式案例如下:
    • axios案例:
      const formData = new FormData()
      formData.append('name', 'chp')
      formData.append('age', '23')
      formData.append('sex', 'male')
      
      this.$api.post('/prefix/multi', formData, {
        headers: {
          'Content-Type': 'multipart/form-data'
        }
      }).then(res => {
        console.log('res', res)
      })
      

    最常见的情境是:在写邮件时,向邮件后添加附件,附件通常使用表单添加,也就是用multipart/form-data格式上传到服务器。

    The encoding type application/x-www-form-urlencoded is inefficient for sending large quantities of binary data or text containing non-ASCII characters. Thus, a new media type,multipart/form-data, is proposed as a way of efficiently sending thevalues associated with a filled-out form from client to server.

    问:为什么要新增一个类型,而不使用旧有的application/x-www-form-urlencoded?
    答:因为此类型不适合用于传输大型二进制数据或者包含非ASCII字符的数据。平常我们使用这个类型都是把表单数据使用url编码后传送给后端,二进制文件当然没办法一起编码进去了。所以multipart/form-data就诞生了,专门用于有效的传输文件。

    • application/x-www-form-urlencoded 对于发送大量二进制数据或包含非ASCII字符的文本效率低下。
    • multipart/form-data 应该用于提交包含文件,非ASCII数据和二进制数据的表单。

    相关知识:比较其中的异同点

    enctype 默认"application/x-www-form-urlencoded"对表单数据进行编码,数据以键值对在http请求体重发送给服务器;如果enctype 属性为"multipart/form-data",则以消息的形式发送给服务器。

    application/x-www-form-urlencoded 形式的参数其实很像用 get 发送的,但是 get 没有body,所有get请求是直接放在尾部的

    相关知识:express自建服务器代码需要注意的

    需要引入 bodyParser 库,不然 express 回调里的 req 里面没有 body。

    const bodyParser = require('body-parser')
    // 支持 application/x-www-form-urlencoded 格式
    app.use(bodyParser.urlencoded({ extended: true }));
    // 支持 application/json 格式
    app.use(bodyParser.json())
    

    参考文档

    POST提交数据之---Content-Type的理解
    HTTP中的Content-Type
    HTTP请求中 request payload 和 formData 区别?
    为什么上传文件要使用multipart/form-data
    MDN:Content-Type

  • 相关阅读:
    win10安装mysql5.7.20解压版
    mvn snapshot
    git SSH key
    Grails踩坑记
    oracle数据库中使用hibernate生成表不能正确创建表
    有些人
    制定短期计划(3月9-4.29)
    有些话
    Linux中mysql主从复制
    Linux下安装mysql
  • 原文地址:https://www.cnblogs.com/can-i-do/p/13712005.html
Copyright © 2011-2022 走看看