常见的四种post提交数据编码格式

HTTP/1.1 协议规定的 HTTP 请求方法有 OPTIONS、GET、HEAD、POST、PUT、DELETE、TRACE、CONNECT 这几种。
其中 POST 一般用来向服务端提交数据,具体到项目中,前后端交互时必须首先约定编码方式,本文主要讨论 POST 提交数据的几种编码方式。

POST请求的编码方式

HTTP协议规定 POST 提交的数据必须放在消息主体(body)中,但协议并没有规定数据必须使用什么编码方式。
服务端通常是根据请求头headers中的 Content-Type 字段来获知请求中的消息主体是用何种方式编码,再对body进行解析。
所以用post方法提交数据,必须指定Content-Type头,如果不指定,浏览器会添加默认的Content-Type头。

目前常见的 POST 提交数据方式见下

1. application/x-www-form-urlencoded

form表单提交,自动添加Content-Type头

html中的form标签可以实现表单提交数据,form的enctype属性用于设置编码方式,默认值为application/x-www-form-urlencoded,发送请求时Content-Type头为application/x-www-form-urlencoded

<form action="/api/login" method="post" enctype="application/x-www-form-urlencoded">
  <p>用户名: <input type="text" name="username" value="admin"></p>
  <p>密码: <input type="test" name="password" value="123456"></p>
  <input type="submit" value="登录" >
</form>

编码方式为 application/x-www-form-urlencoded时,数据在发送到服务器之前,会将表单内的数据转换为键值对(所有的字段都被作为字符串处理),字段形式为fieldname=value,用&分隔每个字段。比如,username=admin&password=123456,并将所有字符都会进行URL 转码。
在线URL编码解码:http://tool.chinaz.com/tools/urlencode.aspx

form的enctype属性值
描述
application/x-www-form-urlencoded在发送前编码所有字符(默认)
multipart/form-data不对字符编码,在使用包含文件上传控件的表单时,必须使用该值。
text/plain空格转换为 “+” 加号,但不对特殊字符编码。
Ajax 提交数据,手动设置Content-type
var xhr=new XMLHttpRequest();
xhr.open("POST","https://www.fastmock.site/mock/d6b39fde63cbe98a4f2fb92ff5b25a6d/api/add",true);
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");

2、multipart/form-data

编码方式为 multipart/form-data时需要首先在HTTP请求头设置一个分隔符,即:boundary的属性值,然后,将每个字段用分隔符分隔,最后一个分隔符表示结束。
数据将被编码为一条消息,由于存在分隔符,既可以上传键值对,也可以上传文件,通常用于上传二进制的文件。

form表单提交

如果使用表单上传文件,需要将表单的enctype设置为multipart/form-data

<form action="/api/upload" method="post" enctype="multipart/form-data">
  <input type="file" name="thumbnail">
  <input type="test" name="caption">
  <input type="submit" value="提交" >
</form>

在这里插入图片描述

可以在js中创建一个FormData对象提交数据,使用 FormData对象,浏览器会自动识别并添加请求头 Content-Type: multipart/form-data
下面是一个带预览功能的上传图片的例子:

<div>
  <img src="" id="img">
  <input type="file" id="thumbnail">
  <button id="btn">上传</button>
</div>
<script>
window.onload=function () {
  var btn=document.getElementById("btn");
  var file = document.getElementById('thumbnail');
  var img = document.getElementById('img');
  //图片预览
  file.addEventListener('change',function (event) {
    var uploadFile = event.target.files[0]
    if (uploadFile) {
      var reader = new FileReader();// 创建流对象
      reader.readAsDataURL(uploadFile)
    }
    reader.onload = function(e) {
      img.src = e.target.result
    }
  })
  //图片上传
  btn.addEventListener('click',function () {
    var formData = new FormData();
    formData.append("caption", "缩略图");
    formData.append('thumbnail', file.files[0]);
    var xhr= new XMLHttpRequest();
    xhr.open("POST", "http://localhost:5000/api/upload");
    xhr.send(formData);
  })
}
</script>

3、application/json

目前常用的Content-Type类型,用来告诉服务端消息主体是序列化后的 JSON 字符串。一些前端框架中post请求默认采用这种编码方式。前端无法将表单的enctype属性指定为application/json,通常使用ajax的方式发送这种编码形式的请求。

var xhr= new XMLHttpRequest();
xhr.open("POST","/api/",true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.send(JSON.stringify({"login_name": "test", "login_password": "123456"}));

ajax发送上述三种编码格式的区别

var xhr1 = new XMLHttpRequest();
xhr1.open("POST", "http://localhost:5000/api/users/login", true);
xhr1.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr1.send("login_name=test&login_password=123456");

var xhr2 = new XMLHttpRequest();
var formData = new FormData();
formData.append("login_name", "test");
formData.append("login_password", "123456");
xhr2.open("POST", "http://localhost:5000/api/users/login", true);
xhr2.send(formData);

var xhr3 = new XMLHttpRequest();
xhr3.open("POST", "http://localhost:5000/api/users/login", true);
xhr3.setRequestHeader("Content-Type", "application/json");
xhr3.send(JSON.stringify({"login_name": "test", "login_password": "123456"}));

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值