缘起

  前段时间遇到扫描问题,好不容易拿到了扫描出来的数据,结果调用接口时弹了个 400(Bad request) 给我,匆匆找了点资料修补上线后,忐忑的心也可以安分点。然后,顺着这个 400 的萝卜,拔出了一大堆的坑。

400 (Bad request)

  400 错误的原因很简单,请求头部信息与请求体中的数据格式不匹配,或者 前 -> 后 的数据中字段类型不一致。在有效沟通的前提下,类型不一致的概率很小,那么这个问题就主要集中在头部信息与请求体数据格式不一致上面了。

  先看一个正确的请求:

$.ajax({
url : "http://localhost:8080/xxx/xxxx",
type : "POST",
contentType: "application/json;charset=utf-8",
data : JSON.stringify({ name, passwd }), // { name, passwd } es6 的一个语法
success : function(result) {
    ...
},
error:function(msg){
  ...
}
})

  目前都是前后端分离的开发模式,两端通信全靠 json,所以,在发送 post 请求时必须得约定并设置请求头 contentType: "application/json;charset=utf-8"。如果不设置的话,这个请求的 contentType 默认 application/x-www-form-urlencoded,一个 415 + 大红叉 顶给你。

  接着,需要设置 data。在发送请求时,如果写成:data: { name, pwd } 的话,服务器还是会返回 400 错误。其实理由也很简单, http 通信过程中,要么就是字符串,要么就是二进制流 ,而 { name, pwd } 是一个对象,必须先转化成字符串或者流,才能传输。于是在请求中,首先得用 JSON.stringify 将 json 对象转换成字符串,这样,服务器才能正确理解请求并拿到数据。

  综上,在 post 请求中,一定要对这两个属性进行设置和处理。

JSON.parse 和 JSON.stringify

  这两个 api 在前端的应用频率也是相当高的,不过,因为某些原因,对 JSON.stringify 这个 api 理解上有些误差。直到最近在查资料时才有了不一样的领悟。

  JSON.parse 将一个 (json) 字符串转换成 (json) 对象,它有个名字是 反序列化;

  JSON.stringify 作用与 JSON.parse 相反,将对象转化成字符串,所以它也有个名字是 序列化。

  序列化 (Serialization)是将对象的状态信息转换为可以 存储 传输 的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。

  尤想起,当年写 class 的时候,序列化与反序列化齐飞,直至今日才明白官方定义...溜了溜了...

POST 常见的数据提交类型 - Content-Type

application/x-www-form-urlencoded

  最常见的 POST 提交数据的方式,原生 form 表单默认的提交方式,同时,如果在 ajax 中不设置的话,同样以这种方式提交。

  这种方式提交的数据会转换成键值对并按照 key1=val1&key2=val2 的方式进行编码,key 和 val 都会进行url 编码。如:

POST http://www.example.com HTTP/1.1
Content-Type: application/x-www-form-urlencoded;charset=utf-8 name=test&val1=1&val2=%E6%B5%8B%E8%AF%95&val3%5B%5D=2

multipart/form-data

  常用于多文件上传。这种方式将表单数据处理成一条消息,以标签为单元,用分隔符(常见的是 boundary)分开。因为这种方式将数据分割为多个部分,所以它既可以上传键值对,也可以上传文件、多文件。当上传的字段是文件时,会有 Content - Type 来说明文件类型;Content-disposition,用来说明字段的一些信息。每部分以 -boundary 开始,紧接着是内容描述信息,然后是回车,最后是字段具体内容(字段、文本或二进制等)。如果传输的是文件,还要包含文件名和文件类型信息。消息主体最后以 -boundary- 标识结束。

  如:(没太看明白)

POST http://www.example.com HTTP/1.1
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA ------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="text" title
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="file"; filename="chrome.png"
Content-Type: image/png PNG ... content of chrome.png ...
------WebKitFormBoundaryrGKCBY7qhFd3TrwA--

application/json

  这个头应该会很熟悉,这也是日常用的比较多的请求/响应头。这个消息头的作用是告诉服务端消息主体是序列化后的 JSON 字符串。

  顺手也贴一个:

POST http://www.example.com HTTP/1.1
Content-Type: application/json;charset=utf-8 {"title":"test","sub":[1,2,3]}

text/plain

  这个消息类型是文件已被设置为纯文本形式,浏览器、服务器收到这种类型的数据不会进行进一步的处理,开发者需要自行判断处理。也支持发送 JSON 字符串。

  这个类型意味着消息自由性变大。

text/xml 和 application/xml

  这两消息类型年代久远...至少在 web 前端领域做实际项目的时候完全没有碰到过。以 xml 文档的形式发送数据。不过因为 xml 严谨结构,对 web 前端来说,这会产生更多的流量,基本被弃用。

  然后这两者的区别是前者默认使用 ‘us-ascii’ 字符集编解码,后者默认 'utf-8' 字符集编解码;前者只能在消息头 content-type 中设置编解码格式才有效,后者在消息头或者在文档内部中设置均可以。

由 POST 400 错误拔出来的萝卜的更多相关文章

  1. 在使用 HttpWebRequest Post数据时候返回 400错误

    笔者有一个项目中用到了上传zip并解压的功能.开始觉得很简单,因为之前曾经做过之类的上传文件的功能,所以并不为意,于是使用copy大法.正如你所料,如果一切很正常的能运行的话就不会有这篇笔记了. 整个 ...

  2. Yii框架 400 错误

    YII  400错误 在YII框架中400错误是csrf校验失败的意思 csrf是什么? CSRF(Cross-site request forgery跨站请求伪造,也被称为"One Cli ...

  3. 解决YII提交POST表单出现400错误,以及ajax post请求时出现400问题

    POST表单400错误: 正确做法: Add this in the head section of your layout: <?= Html::csrfMetaTags() ?> -- ...

  4. request.GetResponse 400错误处理方法

    问题描述:在使用request.GetResponse时,如果是400错误,将抛出异常信息,而获取不到返回内容,所以返回的内容只能在catch上面获取,转载于 http://blog.csdn.net ...

  5. Yii2请求,报400错误

    出现400错误是yii2.0的csrf防范策略导致 在components里面添加request配置如下: 'request' => [ // !!! insert a secret key i ...

  6. 访问本机的WEB API 报400错误

    当时用的IP是127.0.0.1 报400错误,换成 localhost 后正常.

  7. SpringMVC + Spring + MyBatis 学习笔记:提交数据遭遇基础类型和日期类型报400错误解决方法

    系统:WIN8.1 数据库:Oracle 11GR2 开发工具:MyEclipse 8.6 框架:Spring3.2.9.SpringMVC3.2.9.MyBatis3.2.8 使用SpringMVC ...

  8. http 400 错误的请求怎么解决

    HTTP400是个错误的统称 你将IE选项-高级中的显示HTTP友好错误信息前面的勾去掉. 然后在开这个页,,把错误代码复制出来 .其实有时是网页本身已经不可用了,你先关掉浏览器稍等一会再登陆网页也是 ...

  9. http status 400,http 400,400 错误

    转载:http://blog.csdn.net/xu_zh_h/article/details/2294233 4 请求失败4xx 4xx应答定义了特定服务器响应的请求失败的情况.客户端不应当在不更改 ...

随机推荐

  1. 20175329 2018-2019-3《Java程序设计》第三周学习总结

    学号 20175329 2018-2019-3<Java程序设计>第三周学习总结 教材学习内容总结 第四章 第四章主要介绍JAVA中的类与对象的划分,其中有很多复杂的概念以及知识点需要花很 ...

  2. N维偏序:cdq分治

    cdq(陈丹琦)分治,是一种类似二分的算法.基本思想同分治: 递归,把大问题划分成若干个结构相同的子问题,直到(L==R): 处理左区间[L,mid]对右区间[mid+1,R]的影响: 合并. 它可以 ...

  3. object detection[YOLO]

    这部分,我们来聊聊YOLO. YOLO:You Only Look Once,顾名思义,就是希望网络在训练过程中,一张图片只要看一次就行,不需要去多次观察,比如滑框啥的,从而从底层原理上就减少了很多的 ...

  4. 错误 103 未能加载文件或程序集“Telerik.Web.UI”或它的某一个依赖项。磁盘空间不足。 (异常来自 HRESULT:0x80070070)

    运行vs2010时出现错误: 错误 103 未能加载文件或程序集“Telerik.Web.UI”或它的某一个依赖项.磁盘空间不足. (异常来自 HRESULT:0x80070070) 处理方式:清理C ...

  5. .NET(C#)主流ORM总揽

    前言 在以前的一篇文章中,为大家分享了<什么是ORM?为什么用ORM?浅析ORM的使用及利弊>.那么,在目前的.NET(C#)的世界里,有哪些主流的ORM,SqlSugar,Dapper, ...

  6. Typescript 发布到npm

    https://blog.csdn.net/yiershan1314/article/details/79999726 https://cloud.tencent.com/developer/arti ...

  7. vue-area-linkage Vue省市区三级列表联动插件使用

    官方演示地址 // v5及之后的版本 数据依赖于area_data npm i --save vue-area-linkage area-data import Vue from 'vue'; imp ...

  8. mysql安装设置mysql字符集utf8及修改密码

    MySQL的下载,建议下载MySQL的解压缩版本 MySQL官网下载推荐别下最新版本的原因是因为很多之前用的jar包和工具类不兼容最新版本的 可以下5.多的和六点多的 这样的压缩包解压再配置就行了 安 ...

  9. Streaming Principal Component Analysis in Noisy Settings

    论文背景: 面对来袭的数据,连续样本不一定是不相关的,甚至不是同分布的. 当前,大部分在线PCA都只关注准确性,而忽视时效性! 噪声?数据缺失,观测有偏,重大异常? 论文内容: Section 2 O ...

  10. SpringCloud微服务架构分布式组件如何共享session对象

    一.简单做一个背景说明1.为说明问题,本文简单微服务架构示例如下 2.组件说明分布式架构,每个组件都是集群或者主备.具体说明如下:zuul service:网关,API调用都走zuul service ...