# request line

简要地描述了客户端想要如何操作服务器端的资源，比如 `GET / HTTP/1.1`

![](https://605825044-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FVUa7MztTVfoHQxXozBQf%2Fuploads%2FTISd2Yeu6dOqtpE99OzN%2Fimage.png?alt=media\&token=6488b640-0645-43bf-85e7-e9226511827d)

<table><thead><tr><th width="120">组成部分</th><th width="109"> </th><th>说明</th></tr></thead><tbody><tr><td>method</td><td>请求方法</td><td>是一个动词，表示对资源的操作，如 GET/POST</td></tr><tr><td>URI</td><td>资源 path</td><td>标记了请求方法要操作的资源位置</td></tr><tr><td>version</td><td>版本号</td><td>表示报文使用的 HTTP 协议版本</td></tr></tbody></table>

以上三个部分通常使用 `space` 来分隔，最后要用 `CRLF` 换行表示结束。

```http
# server 你好
#   我想获取网站根目录下的默认文件
#   我用的协议版本号是 1.1，请不要用 1.0 或 2.0 回复我
GET / HTTP/1.1
```

## request method

请求方法，就是客户端发出的一个动作指令，要求服务器端对 URI 定位的资源执行该动作。

HTTP/1.1 规定了八种方法，字母都必须大写。

<table><thead><tr><th width="121.33333333333331">最常用的</th><th width="184">用途</th><th>说明</th></tr></thead><tbody><tr><td><code>GET</code></td><td>从服务器获取资源</td><td>资源可以是静态的文本、页面、图片、视频，也可以是由 PHP、Java 动态生成的页面或者其它格式的数据</td></tr><tr><td><code>HEAD</code></td><td>获取资源的元信息</td><td><p>和 <code>GET</code> 方法类似，只是服务器不会返回请求的 entity body 数据，只会传回响应头</p><p>可以看做是 <code>GET</code> 的轻量版。比如当要检查某个文件是否存在、是否有最新版本时，就可以发个 <code>HEAD</code> 请求，从而避免传输 body 数据的浪费</p></td></tr><tr><td><code>POST</code></td><td>向指定资源提交数据</td><td>相当于写入数据或上传数据</td></tr></tbody></table>

<table><thead><tr><th width="131.33333333333331">不常用</th><th width="257"></th><th></th></tr></thead><tbody><tr><td><code>PUT</code></td><td>和 <code>POST</code> 类似<br>但也存在微妙的区别</td><td><code>POST</code> 表示 create 的含义<br>而 <code>PUT</code> 表示 update 的含义</td></tr><tr><td><code>OPTIONS</code></td><td>列出可以对资源实行的操作方法</td><td>通常会在响应头的 <code>Allow</code> 字段里返回</td></tr><tr><td><code>CONNECT</code></td><td></td><td>要求服务器为客户端和另一台远程服务器建立一条特殊的连接隧道，此时 web 服务器在中间充当了代理的角色</td></tr><tr><td><code>DELETE</code></td><td>指示服务器删除资源</td><td>由于该动作危险性太大，所以通常服务器不会执行真正的删除操作，而是对资源做一个删除标记。当然，更多时候服务器就直接不处理 DELETE 请求</td></tr><tr><td><code>TRACE</code></td><td>追踪请求</td><td>通常会显示响应的传输路径。多用于对 HTTP 链路的测试或诊断，其本意是好的，但存在漏洞，会泄漏网站的信息，所以 web 服务器通常也是禁止使用该方法的</td></tr></tbody></table>

此外，我们还可以任意添加请求动作，只要请求方和响应方都能理解就行。比如著名的愚人节玩笑 RFC2324 定义了协议 HTCPCP，还有已经得到了实际应用的请求方法（WebDAV）如 MKCOL, COPY, MOVE, LOCK, UNLOCK, PATCH 等。

## 安全与幂等

在 HTTP 协议里，“安全”是指请求方法不会破坏服务器上的资源，即不会对服务器上的资源造成实质的修改。“幂等”是指多次执行相同的操作，结果都相同，即多次“幂”后结果“相等”，它实际上是一个数学用语，被借用到了 HTTP 协议里。

<table><thead><tr><th width="131.33333333333331">请求方法</th><th width="88">安全</th><th width="82">幂等</th></tr></thead><tbody><tr><td><code>GET</code><br><code>HEAD</code></td><td>✔️</td><td>✔️</td></tr><tr><td><code>POST</code></td><td>❌</td><td>❌</td></tr><tr><td><code>PUT</code><br><code>DELETE</code></td><td>❌</td><td>✔️</td></tr></tbody></table>

关于幂等的说明：

* `POST` 可以理解成 SQL 里的 insert，多次 insert 会添加多条记录
* `PUT` 可以理解成 SQL 里的 update，多次 update “只操作一条记录”
* `DELETE` 可以多次删除同一个资源，效果都是“资源不存在”
