youngwind / blog

梁少峰的个人博客
4.66k stars 385 forks source link

浅谈http报文与请求体格式 #72

Open youngwind opened 8 years ago

youngwind commented 8 years ago

问题

在做项目的时候碰到这样一个问题:前端用fetch发送一个post请求到后端,数据写在body上,后端返回错误。前端代码大概如下:

fetch('/users', {
  method: 'POST',
  headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    name: 'Hubot',
    login: 'hubot',
  })
})

一开始我并不知道错误的原因,照着别人的代码改成大概下面这个样子就好了。

fetch('/users', {
  method: 'POST',
  headers: {
    'Content-Type':'application/x-www-form-urlencoded'
  },
  body: 'name=Hubot&login=hubot'
})

我开始意识到很可能是因为我对http协议不熟悉的原因,所以又去翻了《http权威指南》,学到了不少东西。

http报文格式

每一个http报文都包含下面的三个结构:起始行、首部和主体。(当然,有时候主体可能为空) 2016-05-16 1 28 59

我稍微整理了一下一些常见的字段。(因为字段真的太多了。。。) http

POST、PUT等请求的主体格式

上面并没有详细提到主体(entity body),因为get请求的entity body为空。当我们需要将一些数据发送到服务器保存起来的时候,就常常需要用到post或者put方法。这个时候主体(也叫请求体)的格式就至关重要。header中的content-type值要与body中数据组织方式保持一致。 常见的post请求主体格式可以参考这篇文章:https://imququ.com/post/four-ways-to-post-data-in-http.html

OPTIONS请求

我在使用github的fetch的时候发现:当我发起一个跨域post请求的时候,往往会先发起一个options请求,后来研究了一下,发现这是跨域请求的一个标准。具体可以参考这里:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS