请求过程
一个HTTP请求,从浏览器中输入网址到浏览器显示内容,一共会有这么几个过程:
- DNS解析
- 建立连接
- 发送请求
- 接收请求
- 页面渲染
DNS解析
主要是将URL翻译为具体的IP地址的过程。
浏览器访问DNS服务器(UDP:53),然后DNS服务器通过递归的方式调用根服务器,返回对应的DNS解析结果。
建立连接
服务器端常驻一个服务用以监听80(443)端口,通过TCP的三次握手,可以在服务器和客户端之间建立一个TCP/IP连接:
- 客户端通过自己的某个端口发送TCP建立连接的请求{SYN:1,ACK:0,seq:x},
- 服务器端返回{SYN:1,ACK:1,seq:x+1}
- 客户端回发{ACK:1,seq:x+1,ack=y+1}
当成功建立了连接之后,客户端开始发送HTTP请求
发送请求
HTTP的请求包含了HTTP请求头和body(GET类请求没有body)
一个最简单的HTTP请求:
GET / HTTP/1.1
Host: www.baidu.com
- GET 代表请求方法 其他的例如POST DELETE UPDATE ...
- / 代表请求资源路径(uri) 是相对于host主机的一个路径
- HTTP/1.1 代表HTTP协议版本号 目前通用的是HTTP/1.1 HTTP/2实现了一些新的特性,能够让网页加载速度更快
- Host: 请求主机
除此之外还有另一些常用的请求字段:
- User-Agent 代表请求客户端标识 通常以此区分客户端的类型(Chrome|火狐|IE、桌面端|移动端)
- Cache-Control 指定请求和响应遵循的缓存机制
- Cookie 服务器端据此区分不同的客户端(保存登陆信息)
接收请求
使用telnet模拟一次HTTP请求的结果:
banixc@ubuntu:~$ telnet www.baidu.com 80
Trying 14.215.177.38...
Connected to www.a.shifen.com.
Escape character is '^]'.
GET / HTTP/1.1
HOST:www.baidu.com
HTTP/1.1 200 OK
Date: Sat, 02 Sep 2017 14:32:09 GMT
Content-Type: text/html
Content-Length: 14613
Last-Modified: Thu, 31 Aug 2017 03:03:00 GMT
Connection: Keep-Alive
Vary: Accept-Encoding
Set-Cookie: BAIDUID=D04B686C680A1398ABD46F732D220667:FG=1; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Set-Cookie: BIDUPSID=D04B686C680A1398ABD46F732D220667; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Set-Cookie: PSTM=1504362729; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
P3P: CP=" OTI DSP COR IVA OUR IND COM "
Server: BWS/1.1
X-UA-Compatible: IE=Edge,chrome=1
Pragma: no-cache
Cache-control: no-cache
Accept-Ranges: bytes
<!DOCTYPE html><!--STATUS OK-->
<html>
<head>
...
可以看到
返回的内容中包含了一个很长的头部:
- HTTP/1.1 200 OK 协议版本 状态码 状态描述
- Content-Type: text/html 正文类型 这里是html
- Set-Cookie: 告知浏览器需要为这个域设置一个Cookie
然后空一行后是返回体
页面渲染
页面渲染部分主要由浏览器来实现:
- 解析HTML
- 请求本页的其他资源
- 加载 CSS 图片 以及其他内容
- 执行JavaScript
然后一次HTTP请求就算完成了。
关于长连接
在HTTP/1.0中需要在请求头设置 Connection: Keep-Alive 并设置超时时间 Keep-Alive: timeout=20 或超时次数,在HTTP/1.1中则不需要。若要在HTTP/1.1中设置短连接则需要设置 Connection: close
然而在请求中声明长连接后只是起到通知服务器端的作用,具体是否为长连接还需要服务器的支持。
网友评论