get和POST请求Content-Type不同数据传参方式不同

前言

HTTP 协议是以 ASCII 码传输,建立在 TCP/IP 协议之上的应用层规范。规范把 HTTP 请求分为三个部分:状态行、请求头、消息主体。类似于下面这样:

<method> <request-URL> <version>
<headers>
 
<entity-body>

协议规定 POST 提交的数据必须放在消息主体(entity-body)中,但协议并没有规定数据必须使用什么编码方式。实际上,开发者完全可以自己决定消息主体的格式,只要最后发送的 HTTP 请求满足上面的格式就可以。
但是,数据发送出去,还要服务端解析成功才有意义。一般服务端语言如 php、python ,java等,以及它们的 framework,都内置了自动解析常见数据格式的功能。服务端通常是根据请求头(headers)中的 Content-Type 字段来获知请求中的消息主体是用何种方式编码,再对主体进行解析。post提交数据有四种方式,下面介绍他们以及前端应该如何传参

Content-Type请求头指定了发送给服务器的数据类型,这决定了data字段的格式。以下是几种常见的Content-Type值及其对应的data格式:

1. application/x-www-form-urlencoded
当Content-Type设置为此值时,data应该是一个URL编码的查询字符串,通常由qs.stringify或类似方法生成。

qs可以将json序列化如下:
let a = {
  name:'june',
  age:26  
}
qs.stringify(a)  //"name=june&age=26" qs可以将josn对象转换成形如key&value
 
如何使用:
import qs from 'qs'
let data = {code: 'fds', headImgUrl: '99', innerDemoVos: [{code: '篮球', name: 'xx'}, {code: '台球', name: '小芳'}]}
let params = qs.stringify(data, {arrayFormat: 'indices', allowDots: true})
 
// post的content-type的格式需要设置成application/x-www-form-urlencoded,data就是post请求体。
let data = {code: 'fds', headImgUrl: '99', innerDemoVos: [{code: '篮球', name: 'xx'}, {code: '台球', name: '小芳'}]};
// 将json对象转换成form表单的key&value的形式,包括复杂的数组对象,注意{arrayFormat: 'indices', allowDots: true}参数,一定要写,这个关系到数组对象转换成的格式后台是否可以解析,如果不写那么数组对象就是innerDemo[0].[code]: 篮球,这样后台是无法解析,只有innerDemo[0].code: 篮球的格式才可以解析,
console.info(qs.stringify(data, {arrayFormat: 'indices', allowDots: true}));
这是默认的编码方式,‌表单数据会被编码为键值对形式,‌通常用于提交表单。‌在这种方式下,‌参数以键值对的形式出现在请求体中,‌键和值之间使用"="连接,‌而不同的键值对之间使用"&"分隔。‌这种方式适合传输简单的键值对数据。‌

2. application/json
当Content-Type设置为application/json时,data应该是一个JSON字符串,可以通过JSON.stringify方法转换一个JavaScript对象来得到。

  let param = {
    name : 'xiaohong',
    age: 18,
    sex: '女',
    goods: {
        a: 1,
        b:2
    }
}

传参直接传json对象param,非常简单

当需要传输复杂的数据结构时,‌如对象或数组,‌通常会使用JSON格式。‌JSON数据是一种轻量级的数据交换格式,‌易于阅读和编写,‌同时也易于机器解析和生成。‌在HTTP请求中,‌JSON数据作为请求体发送,‌服务器端可以通过解析JSON数据来获取请求的具体内容。‌

3. multipart/form-data
这个Content-Type通常用于上传文件,此时data应该是一个FormData对象,可以使用new FormData()创建,并通过append方法添加键值对或文件。

const formData = new FormData();

// 添加键值对
formData.append('username', 'john_doe');
formData.append('password', 'secret');

// 添加文件
const fileInput = document.getElementById('file-input');
const file = fileInput.files[0];
if (file) {
  formData.append('avatar', file, file.name);
}

// 发送请求
const response = await fetch('/api/upload', {
  method: 'POST',
  body: formData
});

// 处理响应
const data = await response.json();
console.log(data);
这种编码方式适合上传文件等需要分割的数据。‌它可以将表单数据编码为一条一条的消息,‌每一条消息都可以有自己的头部信息,‌允许同时上传多个文件或表单数据。‌

4.text/plain
这种方式适合传输纯文本数据,‌数据以纯文本形式出现在请求体中,‌不进行任何编码或格式化。‌

因此,根据Content-Type的不同,data的格式会有所变化,以适应不同的请求需求。

get方式和post方式的区别:

get方式没有http-body。参数在url中key=value形式传递。对值进行URLencode编码。

post方式和get方式对立。包含http-body。把数据放到http-body中。

根据以上的描述,可以总结:

get方式的请求:Content-Type只能为application/x-www-form-urlencoded。没有别的选择。

post方式的请求:Content-Type可以选择application/x-www-form-urlencoded , multipart/form-data , application/json,三种方式。

在vue中Axios传参json可以不需要JSON.stingify对data进行转换
在现代Web开发中,尤其是使用诸如Axios、Fetch API等较新的HTTP客户端库时,有时候我们不再显式地使用 JSON.stringify() 来序列化对象,这是因为这些库内部已经处理了数据序列化的问题。以下是一些原因:

  1. 自动序列化: 现代的HTTP客户端库如Axios和Fetch
    API能够自动识别Content-Type并相应地序列化数据。当你设置Content-Type为application/json时,它们会自动调用JSON.stringify()来转换JavaScript对象为JSON字符串。
  2. 更简洁的代码:
    直接传递JavaScript对象作为请求体参数,而不是先调用JSON.stringify(),可以使代码更加简洁和易于阅读。
  3. 减少错误: 自动序列化减少了手动序列化可能引入的错误,比如忘记调用JSON.stringify()或序列化失败导致的错误。
  4. 统一的接口: 现代库提供了更统一的接口,使得无论是GET还是POST请求,数据的处理方式都更加一致,不需要关心底层的细节。

然而,这并不意味着JSON.stringify()已经过时或完全不需要了。在某些情况下,你仍然需要使用它,例如:

 当你直接操作XMLHttpRequest或使用不支持自动序列化的旧库时。
 当你需要手动控制序列化过程,例如使用replacer或space参数时。
 当你正在编写与JSON数据交互的通用工具函数或库时。

总的来说,是否使用JSON.stringify()取决于你使用的具体库或框架以及你对数据序列化的需求。在大多数现代Web开发项目中,你可能不需要频繁地直接调用JSON.stringify(),而是依赖于更高层次的抽象来处理这些细节。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值