浏览器访问服务器的过程
1/用户输入网址
2/浏览器请求DNS服务器,获取域名对应的IP地址(电脑连上网之后会被自动分配一个DNS服务器,域名跟ip是以键值对的形式存在DNS服务器,会按一定规则更新,)
3/请求连接该IP地址服务器
4/发送资源请求(HTTP协议)
5/web服务器接收请求,并解析请求,判断用户意图
6/获取用户想要的资源.
7/将资源返回给web服务器程序.
8/web服务器程序将资源数据通过网络发送给浏览器.
9/浏览器解析请求的数据并且完成网页数据的显示.
URL
网址有称为URL,URL的英文全拼是(Uniform Resoure Locator),表达的意思是统一资源定位符,通俗理解就是网络资源地址。
HTTP协议介绍
HTTP协议就是超文本传输协议(HyperText Transfer Protocol),通俗理解是浏览器和web服务器传输数据格式的协议,HTTP协议是一个应用层协议。
HTTP协议是基于TCP协议的,发送数据之前需要建立好连接
HTTP是万维网的数据通信的基础。设计HTTP最初的目的是为了提供一种发布和接收HTML页面<网页>的方法。
HTTP协议的制作者是蒂姆·伯纳斯-李,他供职于CERN(欧洲核子研究组织)
1991年发布的0.9版,该版本极其简单,只有一个GET请求方法
1996年5月,HTTP/1.0版本发布
1997年1月,HTTP/1.1版本发布,目前使用就是HTTP/1.1版本
网络传输-TCP/IP四层模型
TCP/IP模型又称为TCP/IP协议族,是一系列网络协议的总称。TCP/IP模型一共包括几百种协议,制作协议的目的,就是保证计算机之间可以进行按照一定格式进行数据通信。
1. 链路层(数据链路层/网络接口层):包括操作系统中的设备驱动程序、计算机中对应的网络接口卡.
2. 网络层:处理分组在网络中的活动,比如分组的选路.
3. 运输层:主要为两台主机上的应用提供端到端的通信.
4. 应用层:负责处理特定的应用程序细节.
HTTP
(底层通过tcp/ip实现)
工作模式
HTTP协议的工作模式是一次请求(request)和一次响应(response)的模式
google查看http协议通信过程(F12)
从浏览器到网络链路层是一个封包的过程,解包的过程恰恰相反
元素(Elements):用于查看或修改HTML元素的属性、CSS属性、监听事件、断点等.
控制台(Console):控制台一般用于执行一次性代码, 查看JavaScript对象, 查看调试日志信息或异常信息.
源代码(Sources):该页面用于查看页面的HTML文件源代码、JavaScript源代码、CSS源代码, 此外最重要的是可以调试JavaScript源代码, 可以给JS代码添加断点等.
网络(Network):网络页面主要用于查看header 等与网络连接相关的信息.
注意 : Network中的每一项就是一次请求/响应过程,点击每一项,可查看本次请求响应的报文信息.
HTTP 请求报文协议分析
Request Headers 中就是请求的报文数据内容
(view source)
GET / HTTP/1.1
Host: www.baidu.com
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: en,zh;q=0.9,zh-CN;q=0.8
Cookie: BAIDUID=713881BEC6FEA9B8ED779F0820D52655:FG=1; BIDUPSID=713881BEC6FEA9B8ED779F0820D52655; PSTM=1533258987; BD_UPN=123353; BDUSS=FhjQWE3RGlnWlNTRzlwaVJ5OGlWLVl5RnlOTkw4T2RLczBJU2tqTn5IYjVoNUpiQVFBQUFBJCQAAAAAAAAAAAEAAADOT~BgaGFwcHkxMWZseWluZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPn6alv5-mpbT; __cfduid=d6f09ee5aa1a7ddcff9c0f4ee3cc9ab5d1535199109; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; delPer=0; BD_HOME=1; H_PS_PSSID=27022_1437_26909_21092_27153
-
GET / HTTP/1.1 叫做请求行. 里面包含3个信息, 以空格隔开,
-
第一个叫做请求方法, 除了GET 方法之外, 还有POST 方法, 除此之外还有HEAD方法, 这两种最常用. GET 主要用于从服务器获得数据, POST 主要用于从浏览器提交数据到服务器. 比如像百度首页提供的上传图片的功能, 就是用POST方式.
-
第二个表示请求的资源路径.当请求的URL是
https://www.baidu.com/
,那么我们会发现路径会显示’/’,那么如果请求的URL是
https://www.baidu
. com/index.html ,我们会发现路径显示是’/index.html’. -
第三个表示HTTP 协议的版本, 那么既然有1.1版本, 前置版本肯定是1.0了,那么两个版本有什么区别呢? 1.1版本比1.0的版本主要多个一些请求方法等扩充协议的内容.
-
Host 表示浏览器要请求的主机地址
-
Connection 表示浏览器和服务器之间的连接方式, 浏览器和服务器连接是长连接还是短连接, keep-alive表示长连接,close表示短连接
- 长连接: 连接建立成功后,可以发送多次请求和响应,等双方不进行通信的时候,服务端做好断开连接的操作
- 短连接: 连接建立成功后,一次请求和响应完成以后连接就会断开,每次发送请求需要先建立好连接
- 长连接可以省去较多的TCP建立和关闭的操作,节约时间。但是如果用户量太大容易造成服务器负载过高最终导致服务不可用
- 短连接对于服务器来说实现起来较为简单,存在的连接都是有用的连接,不需要额外的控制手段。但是如果用户访问量很大, 往往可能在很短时间内需要创建大量的连接,造成服务器响应速度过慢
- User-Agent 用户代理:可以识别是通过什么程序发出的请求,比如chrome, firefox, python程序
- Accept 表示浏览器告诉服务器, 自己能够接收并识别的文件类型.
- Accept-Encoding 表示浏览器能够处理的压缩方式. 为什么需要压缩呢?当网页数据量大的时候, 压缩之后可以提高传输速率, 提高用户体验.
- Accept-Language 浏览器可以接收的文本语言, 如果非中文编码可能会出现乱码.
-
* HTTP请求报文可以分为GET请求和POST请求报文,要注意的是GET请求没有请求体,POST请求有请求体信息*
-
HTTP 响应报文协议分析(Response Headers)
HTTP/1.1 200 OK
Bdpagetype: 2
Bdqid: 0xb11b33c2000089e5
Cache-Control: private
Connection: Keep-Alive
Content-Encoding: gzip
Content-Type: text/html;charset=utf-8
Date: Mon, 10 Sep 2018 01:47:43 GMT
Expires: Mon, 10 Sep 2018 01:47:43 GMT
Server: BWS/1.1
Set-Cookie: BDSVRTM=263; path=/
Set-Cookie: BD_HOME=1; path=/
Set-Cookie: H_PS_PSSID=27022_1437_26966_21092_27153; path=/; domain=.baidu.com
Strict-Transport-Security: max-age=172800
X-Ua-Compatible: IE=Edge,chrome=1
Transfer-Encoding: chunked
-
第一行HTTP/1.1 200 OK 叫做响应行, 共分成3部分,
- 第一部分HTTP/1.1 表示HTTP协议的版本,
- 第二部分是一个数字, 这个数字表示响应状态码, 用户向服务器发出了请求, 如果服务器正常返回响应报文, 那么状态码一般都是200,
-
第三部分的”OK” 表示原因短语, 表示对前面状态码的简单描述. 这里需要说的是, 响应的状态码除了200 之外,还有其他的状态码, 下面是常见的状态码:
- 302 redirect, 我们通过302 状态码可以指示浏览器跳转到某一个URL.
- 404 NOT FOUND, 当我们访问一个不存在的URL 时, 一般会返回404状态码, 告诉浏览器, 你访问的URL 是不存在的.
- 500 Internal Server Error, 服务器遇到了一个未曾预料的状况, 导致了它无法完成对请求的处理. 一般来说, 这个问题都会在服务器端的源代码出现错误时出现.
-
第二行下面的所有内容, 我们叫做响应头. Content-Type 表示响应内容的文本格式和编码方式.
HTTP协议响应报文分为4部分,每部分之间使用\r\n进行分割
响应行
响应头
空行(\r\n)
响应体
模仿浏览器访问百度
from socket import AF_INET, SOCK_STREAM, socket
client = socket(AF_INET, SOCK_STREAM)
client.connect(('baidu.com', 80)) # 可以通过域名访问, 浏览器一般访问80端口
# 请求行
request_line = "GET / HTTP/1.1\r\n"
# 请求头
request_header = "Host: baidu.com\r\nConnection: close\r\n"
request_content = request_line + request_header + "\r\n"
client.send(request_content.encode("utf-8"))
# 定义二进制数据的响应类型
result = b""
while True:
# 提示: 服务端断开连接,recv会解阻塞,返回的数据长度0
# 提示: 以后可以通过Content-Length判断服务端发送数据的长度,或者数据末尾会有0\r\n
recv_data = client.recv(1024)
if recv_data:
result += recv_data
else:
break
print(result)
response_content = result.decode("utf-8")
response_list = response_content.split("\r\n\r\n", 1)
print(len(response_list))
print(response_list[1])
client.close()
>>>b'HTTP/1.1 200 OK\r\nDate: Mon, 10 Sep 2018 03:18:14 GMT\r\nServer: Apache\r\nLast-Modified: Tue, 12 Jan 2010 13:48:00 GMT\r\nETag: "51-47cf7e6ee8400"\r\nAccept-Ranges: bytes\r\nContent-Length: 81\r\nCache-Control: max-age=86400\r\nExpires: Tue, 11 Sep 2018 03:18:14 GMT\r\nConnection: Close\r\nContent-Type: text/html\r\n\r\n<html>\n<meta http-equiv="refresh" content="0;url=http://www.baidu.com/">\n</html>\n'
2
<html>
<meta http-equiv="refresh" content="0;url=http://www.baidu.com/">
</html>
注意http请求报文的格式: 请求行+ 请求头+ \r\n + 请求体(可选)
注意http响应报文的格式: 响应行+ 响应头+ \r\n + 响应体