情景描述
- create React app中使用fetch 发送跨域http请求
fetch('/todos',{
method: 'POST',
headers: new Headers({
'Content-Type': 'application/json'
})
body:{text,user_id:1}
}).then(.....)
- 使用create React app的proxy进行请求的跨域转发
"proxy": "http://localhost:8080"
- 发送请求
http://localhost:3000/todos
返回状态码400 - 使用postman发送POST请求
http://localhost:8080/todos
选择raw --> application/json
{
"text":"1111",
"user_id":1
} //成功返回状态码201
矛盾
- postman和使用fetch发送的请求body类型完全一致路径完全一致,按照道理来说如果postman能够成功,那么fetch一定也能成功,那么为什么使用fetch发送会出现request body missing 导致400错误?
- 问题可能在于:
- 1.fetch发送json body的用法有误
- 2.postman还设置了别的header
解决
- Q1:400状态码代表什么样的错误?
- A1:400状态码说明你发送的请求服务器接收到了但是不能识别请求内容。
- Q2:postman选择的raw application/json到底是什么格式的请求?
- A2:body tab中的4中不同方式,会对应着不同的head content-type,选择raw就可以向面板中填入任何类型的数据,通过选择application/json确定postman会发送一个使用json解析器能够解析的实体到服务器。
- Q3:请求head中content-type有什么作用?
- A3:Content-Type属性作用其实是:当你发送请求设置Content-Type:application/json,就是相当于告诉服务器,你应该采用解析json的方式解析我的请求体,但是请求体是否是json格式就不一定了。如果未指定 ContentType,默认为text/html。因此说明此时我告诉了服务器用json解析器解析body。
Q4:fetch post json的标准方式是什么呢?
-
A4:查询官网发现
fetch('/users', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name: 'Hubot', login: 'hubot', }) })
发现官网上使用了json.stringify,因此确定问题原因:我没有使用fetch正确的传送json body的格式。
- Q5:那么为什么postman成功了,但是fetch没有?
- A5:首先postman一定能够把你输入的对象变成使用Application/json就能解析的形式发送给服务器,然而这个过程我们是看不到的。如果仅仅把body写成相同的样子,fetch会把这个body包装成什么样子发走我们不知道。因此postman和fetch即使body完全一致header完全一致,也不一定结果一样。fetch需要把body stringify了之后发走才能使用Application解析。
我的错误点
- 错误的以为content-type的作用是把body变成某种类型。其实他只是告诉服务器使用哪种方式解析你的body。
反思
- fetch发送请求的方式我并不了解,并且不是很会使用,只是想当然的随便写,写不对再试再试。并没有想到参照官网。
action
- 使用任何新的东西,如果遇到bug,那么应该立刻去看官网对这种问题的做法。