use fetch post send json can not work

情景描述

  • 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,那么应该立刻去看官网对这种问题的做法。

你可能感兴趣的