# HTTP协议入门

HTTP协议是Hypertext Transfer Protocol超文本传输协议的缩写。HTTP协议属于应用层协议，它构建在TCP和IP协议之上，处于TCP/IP体系架构中的顶端，使用TCP/IP协议来传输数据。这样一来它就不必处理下层协议间诸如丢包补发、握手及数据的分段和重新组装等。

![](/files/-M7h5ZkHcaOQNlFttezn)

## 1. 主要特点：

* 简单快速：客户向服务器请求服务时，只需传送请求方法和路径。请求方法常用的有GET、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单，使得HTTP服务器的程序规模小，因而通信速度很快。
* 灵活：HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
* 无连接：无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求，并收到客户的应答后，即断开连接。采用这种方式可以节省传输时间。
* 无状态：HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息，则它必须重传，这样可能导致每次连接传送的数据量增大。另一方面，在服务器不需要先前信息时它的应答就较快。为了解决这个问题，引入cookie和session。

## 2. HTTP请求与响应过程

1. 浏览器根据所使用的HTTP协议，解析出url对应的域名；
2. 通过DNS域名解析，查询出该域名对应的IP地址；
3. 通过URL解析出对应的端口号，如果是80，默认可以省略；
4. 浏览器根据ip和端口建立TCP连接；
5. 浏览器向服务器发送一条HTTP请求报文，比如get请求；
6. 服务器响应请求，并发送给浏览器返回报文；
7. 浏览器渲染网页并关闭与服务器的连接。

**小技巧**

* 在Chrome中查询DNS缓存：

  ```
  chrome://net-internals/#dns
  ```

## 3. HTTP请求的报文格式

一个HTTP请求报文由请求行（request line）、请求头部（request header）、空行和请求数据组成，如下图：

![](/files/-M7h5ZkOzUx34rPV1d7g)

**请求行：** 请求行分为三个部分：请求方法、请求地址和协议版本。

* 请求方法：HTTP/1.1 定义的**请求方法**有8种：GET、POST、PUT、DELETE、PATCH、HEAD、OPTIONS、TRACE。最常的两种GET和POST，如果是RESTful接口的话一般会用到GET、POST、DELETE、PUT。
* 请求地址：URL:统一资源定位符，是一种资源的唯一定位标志。

  组成：<协议>：//<主机>：<端口>/<路径>
* 协议版本：格式为：HTTP/主版本号.次版本号，常用的有HTTP/1.0和HTTP/1.1。

**请求头部：**

请求头部为请求报文添加了一些附加信息，由“名/值”对组成，每行一对，名和值之间使用冒号分隔。

请求头部的最后会有一个空行，表示请求头部结束，接下来为请求数据，这一行非常重要，必不可少。

请求头部内容的详细介绍可以参考：[我的gitbook:HTTP的请求格式](https://wangjun-scu.gitbooks.io/learnjava/content/%E6%8A%80%E6%9C%AF%E5%AD%A6%E4%B9%A0/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/HTTP_POST%E8%AF%B7%E6%B1%82%E7%9A%84%E6%95%B0%E6%8D%AE%E6%A0%BC%E5%BC%8F.html)

**请求数据：**

可选部分，比如GET请求就没有请求数据。

下面是一个POST方法的请求报文：

```
POST 　/index.php　HTTP/1.1 　　 //请求行
Host: localhost  //请求头
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:10.0.2) Gecko/20100101 Firefox/10.0.2　　
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
Accept-Language: zh-cn,zh;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Referer: http://localhost/
Content-Length：25
Content-Type：application/x-www-form-urlencoded
　　//空行
username=aa&password=1234　　请求数据
```

\*注意：\*可以使用谷歌自带的HTTP报文拦截器查看HTTP详细报文

```
chrome://net-internals/
```

## 4. HTTP响应的报文格式

HTTP响应报文主要由状态行、响应头部、空行以及响应数据组成。

![](/files/-M7h5ZkP5TKtjrFTAiwE)

**状态行：**

3部分组成，分别为：协议版本，状态码，状态码描述。

* 状态码：

  状态代码为3位数字。 1xx：指示信息--表示请求已接收，继续处理。 2xx：成功--表示请求已被成功接收、理解、接受。 3xx：重定向--要完成请求必须进行更进一步的操作。 4xx：客户端错误--请求有语法错误或请求无法实现。 5xx：服务器端错误--服务器未能实现合法的请求。

比如200表示响应成功，404表示请求的网页不存在，500表示服务器内部错误等。

**响应头部：**

和请求头部类似，可以参考：[我的gitbook:HTTP的请求格式](https://wangjun-scu.gitbooks.io/learnjava/content/%E6%8A%80%E6%9C%AF%E5%AD%A6%E4%B9%A0/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/HTTP_POST%E8%AF%B7%E6%B1%82%E7%9A%84%E6%95%B0%E6%8D%AE%E6%A0%BC%E5%BC%8F.html)

**响应正文：**

用于存放需要返回给客户端的数据信息。

下面是一个响应报文的实例：

```
HTTP/1.1 200 OK　　//状态行
Date: Sun, 17 Mar 2013 08:12:54 GMT　　//响应头部
Server: Apache/2.2.8 (Win32) PHP/5.2.5
X-Powered-By: PHP/5.2.5
Set-Cookie: PHPSESSID=c0huq7pdkmm5gg6osoe3mgjmm3; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Content-Length: 4393
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=utf-8
　　空行
<html>　　//响应数据
<head>
<title>HTTP响应示例<title>
</head>
<body>
Hello HTTP!
</body>
</html>
```

## 5. GET和POST的区别和联系

1. GET提交的数据会放在URL之后，以?分割URL和传输数据，参数之间以&相连，如EditPosts.aspx?name=test1\&id=123456. POST方法是把提交的数据放在HTTP包的Body中；
2. GET提交的数据大小有限制（因为浏览器对URL的长度有限制），而POST方法提交的数据没有限制，不过一般WEB服务器会对post的请求大小进行限制；
3. GET方式提交数据，会带来安全问题，比如一个登录页面，通过GET方式提交数据时，用户名和密码将出现在URL上，如果页面可以被缓存或者其他人可以访问这台机器，就可以从历史记录获得该用户的账号和密码。

## 6. HTTP的长连接和短连接

在HTTP/1.0中默认使用短连接。也就是说，客户端和服务器每进行一次HTTP操作，就建立一次连接，任务结束就中断连接。当客户端浏览器访问的某个HTML或其他类型的Web页中包含有其他的Web资源（如JavaScript文件、图像文件、CSS文件等），每遇到这样一个Web资源，浏览器就会重新建立一个HTTP会话。

而从HTTP/1.1起，默认使用长连接，用以保持连接特性。使用长连接的HTTP协议，会在响应头加入这行代码：

```
Connection:keep-alive
```

在使用长连接的情况下，当一个网页打开完成后，客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭，客户端再次访问这个服务器时，会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接，它有一个保持时间，可以在不同的服务器软件（如Apache）中设定这个时间。实现长连接需要客户端和服务端都支持长连接。

HTTP协议的长连接和短连接，实质上是TCP协议的长连接和短连接。也就是TCP在一次传输完数据后会不会立即进行四次挥手。

## 7. Cookies和Sessions的区别

1. cookie数据存放在客户的浏览器上，session数据放在服务器上。
2. cookie不是很安全，别人可以分析存放在本地的cookie并进行cookie欺骗，考虑到安全应当使用session。
3. session会在一定时间内保存在服务器上。当访问增多，会比较占用你服务器的性能，考虑到减轻服务器性能方面，应当使用cookie。
4. 单个cookie保存的数据不能超过4K，很多浏览器都限制一个站点最多保存20个cookie。
5. 可以考虑将登陆信息等重要信息存放为session，其他信息如果需要保留，可以放在cookie中。

## 8. HTTP方法

* GET：获取资源。
* POST：向指定资源提交数据进行处理请求 。
* PUT：从客户端向服务器传送的数据取代指定的文档的内容。
* DELETE：请求服务器删除指定的页面。
* HEAD：类似于GET请求，只返回header。
* OPTIONS：询问支持的方法，查询请求URI指定资源支持的方法，体现在响应报文的header中。
* TRACE：回显服务器收到的请求，主要用于测试或诊断。
* CONNECT：要求用隧道协议连接代理。
* LINK和UNLINK：HTTP/1.0协议支持，HTTP/1.1已废弃，不再支持。

> 参考：
>
> <https://blog.csdn.net/yezitoo/article/details/78193794>
>
> <https://www.cnblogs.com/ranyonsue/p/5984001.html>
>
> <https://www.cnblogs.com/gotodsp/p/6366163.html>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://jun-wang.gitbook.io/learnjava/ji-shu-xue-xi/ji-suan-ji-wang-luo/http-xie-yi-ru-men.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
