Tags   Server HTTP

Back

网络通信技术实践: (4)基本HTTP

1 HTTP 简介(部分引自百度百科)

超文本传输协议(Hypertext Transfer Protocol,HTTP)是一个简单的请求-响应协议,它通常运行在TCP之上。它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。当您在浏览器中输入网址时,其开头的http便表示HTTP协议。

HTTP是基于客户/服务器模式,且面向连接的。典型的HTTP事务处理有如下的过程:

  1. 客户与服务器建立连接;
  2. 客户向服务器提出请求;
  3. 服务器接受请求,并根据请求返回相应的文件作为应答;
  4. 客户与服务器关闭连接。

客户端(常常是浏览器)与服务器之间的HTTP连接是一种一次性连接,它限制每次连接只处理一个请求,当服务器返回本次请求的应答后便立即关闭连接,下次请求再重新建立连接。

HTTP协议一般运行在80端口之上。当你输入以http开头的网址而未指定端口时,默认访问80端口。

2 HTTP请求

HTTP规范定义了9种请求方法,每种请求方法规定了客户和服务器之间不同的信息交换方式,服务器将根据客户请求完成相应操作,并以应答块形式返回给客户,最后关闭连接,如下表所示:

方法 说明 出现的HTTP版本
GET 获取资源 1.0
POST 传输实体主体 1.0
HEAD 获得报文首部 1.0
PUT 传输文件 1.1
DELETE 删除文件 1.1
OPTIONS 询问支持的方法 1.1
TRACE 追踪路径 1.1
CONNECT 要求用隧道协议链接代理 1.1
LINK 建立和资源之间的联系 1.1
UNLINE 断开连接关系 1.1

实际上,常用的请求方法只有GETPOST

HTTP请求的格式如下:

  1. 首行: 也叫请求行,包括方法、URL和所用HTTP协议的版本,用一个空格分隔,以换行符\n结尾;
  2. 报头(header): 请求的属性。为每行一个的冒号分割的键值对,即每个键值对用\n分隔。空行(单独一个\n)表示报头部分的结束;
  3. 正文(body): 空行后面的内容都是正文,可以是空字符串。 如果正文存在, 则在报头中会有Content-Length属性来指示正文的长度。

2.1 URL

一个典型的URL为: http://www.example.com:80/path/to/myfile.html?key1=value1&key2=value2#anchor

  1. http:// 表示http协议,常见的还有https, ftp等;
  2. www.example.com 表示域名,其中example.com的部分为主体域名;
  3. 80 表示端口号,80端口即默认http端口,可以省略;
  4. /path/to/myfile.html 表示资源路径,用于定位到程序管理的资源;
  5. ?key1=value1&key2=value2 表示查询字符串,以?开头,可以包含多个键值对,每个键值对以键=值的形式表示,用&分割;
  6. #anchor表示片段标识,以#开头,用于页面内部定位。

2.2 GET请求

GET请求通常用于客户端向服务器请求指定的页面信息,并返回实体内容。一个典型的GET请求如下:

GET /signin?next=%2F HTTP/2
Host: www.zhihu.com
User-Agent: Mozilla/5.0
Accept: */*
Accept-Language: zh-CN
Accept-Encoding: gzip, deflate
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0
TE: trailers
Cookie: uuid=1234567890; something=xxx
(这里有一个空行)

通常地,GET请求没有请求体,只有请求头。GET请求的请求参数以查询字符串的形式出现。 常见参数的解释如下:

  1. Host表示请求的主机;
  2. User-Agent表示浏览器/操作系统的属性,简称UA;
  3. Referer表示是从哪个页面跳转过来的;
  4. Cookie本质上是浏览器给网页提供的本地存储数据的机制。网页默认是不被允许访问计算机的硬盘的,但是浏览器又需要在本地存储一些东西(比如用户登录状态等等),Cookie就是用来完成这项功能的。

2.2 POST请求

POST请求通常用于客户端向服务器发送信息(例如提交表单、登录等)。一个典型的POST请求如下:

POST /login HTTP/1.1
Host: 127.0.0.1:8888
User-Agent: Mozilla/5.0
Accept: */*
Accept-Language: zh-CN
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 29
Connection: keep-alive

username=root&password=123456
POST请求具有请求体,亦即body部分。放在请求体内的请求参数以`key=value`的形式传递,参数与参数之间使用`&`进行连接,同GET请求中的查询字符串一致。

常见参数的解释如下:

  1. Content-Type指示body部分的数据类型;
  2. Content-Length指示body部分的数据长度(以字节为单位)。

3 HTTP响应

当客户端给出请求时,服务端会给出响应,格式如下:

  1. 首行: 也叫请求行,包括所用HTTP协议的版本和响应代码,用一个空格分隔,以换行符\n结尾;
  2. 报头(header): 请求的属性。为每行一个的冒号分割的键值对,即每个键值对用\n分隔。空行(单独一个\n)表示报头部分的结束;
  3. 正文(body): 空行后面的内容都是正文,可以是空字符串。 如果正文存在, 则在报头中会有Content-Length属性来指示正文的长度。
HTTP/1.1 200 OK
Content-Type:text/plain;charset=UTF-8
Content-Length:31
Date:Wed, 19 Jan 2022 11:37:00 GMT
Keep-Alive:timeout=60
Connection:keep-alive
​
post request is ok,param = post

响应代码的含义如下:

代码系列 含义 解释
1xx 临时响应信息 服务器收到请求,需要请求者继续执行操作
2xx 成功 操作被成功接收并处理
3xx 重定向 需要进一步的操作以完成请求
4xx 客户端错误 请求包含语法错误或无法完成请求
5xx 服务器错误 服务器在处理请求的过程中发生了错误

例如:200 OK表示访问成功,404 Not Found表示没有找到要访问的资源,404 Forbidden表示禁止访问(例如没有权限)等,500 Internal Server Error表示服务器内部错误。

4 HTTP请求与响应的Python实现

在Python中,通常使用requests库来实现HTTP请求。该库同时也支持HTTPS(即加密通信的HTTP)。

可以在命令行中输入以下命令安装requests库:

pip install requests

使用范例如下:

import requests

res=requests.get("https://www.baidu.com") #向百度网站发送GET请求
print(res.text) #输出HTTP响应的正文

res=requests.get("https://www.baidu.com", verify=False) #向百度网站发送GET请求,并且不验证SSL证书的有效性,用于阻止某些SSL错误发生

res=requests.get("https://www.baidu.com",cookie={"user":"username"}) #指定请求的Cookie

url = "http://httpbin.org/post"
data = {
  "name": "Tom",
  "age": 20,
}
res=requests.post(url, data=data) #向httpbin.org/post发送POST请求
print(res.text) #输出HTTP响应的正文

有的时候,我们需要维持访问会话(例如有些请求对于是否登录的返回有差别,需要维持cookie),这时候需要使用session功能:

import requests

session = requests.session()
print("会话初始cookie:",dict(session.cookies))

res = session.get("https://postman-echo.com/get")

print("响应头中set-cookie:",res.headers.get("set-cookie"))
print("会话现有cookie:",dict(session.cookies))

HTTP响应通常是服务端的任务。在Python中,常用的服务端开发程序是Flask。由于Flask内容繁多,这里不再详细介绍。

目录

上一节

下一节