Skip to content

Latest commit

 

History

History
278 lines (194 loc) · 9.06 KB

7.1.md

File metadata and controls

278 lines (194 loc) · 9.06 KB

超文本传输协议

原文:HTTP

校验:Kitty Du

自豪地采用谷歌翻译

# HIDDEN
# Clear previously defined variables
%reset -f

# Set directory for data loading to work properly
import os
os.chdir(os.path.expanduser('~/notebooks/07'))

Http

Http(AKA HyperText Ttransfer Protocol)是一种 请求-响应(request-response) 协议,允许一台计算机通过 Internet 与另一台计算机对话。

请求和响应

互联网允许计算机互相发送文本,但不会对文本包含的内容施加任何限制。HTTP 定义了一台计算机(客户端client)和另一台计算机(服务器server)之间的文本通信结构。在这个协议中,客户机向服务器提交一个 请求,是一个特殊格式的文本消息。服务器将送回一个响应文本到客户端。

命令行工具curl为我们提供了发送 HTTP 请求的简单方法。在下面的输出中,以>开头的行表示请求中发送的文本;其余的行是服务器的响应。

$ curl -v https://httpbin.org/html
> GET /html HTTP/1.1
> Host: httpbin.org
> User-Agent: curl/7.55.1
> Accept: */*
> 
< HTTP/1.1 200 OK
< Connection: keep-alive
< Server: meinheld/0.6.1
< Date: Wed, 11 Apr 2018 18:15:03 GMT
< 
<html>
  <body>
    <h1>Herman Melville - Moby-Dick</h1>
    <p>
      Availing himself of the mild...
    </p>
  </body>
</html>

运行上面的curl命令会使客户机的计算机构造一条如下所示的文本消息:

GET /html HTTP/1.1
Host: httpbin.org
User-Agent: curl/7.55.1
Accept: */*
{blank_line}

此消息遵循特定的格式:以GET /html HTTP/1.1开头,表示消息是对/html页的 HTTPGET请求。表单 HTTP 头后面的三行中的每一行,都是curl发送给服务器的可选信息。HTTP 头的格式为{name}: {value}。最后,消息结尾的空白行告诉服务器消息在三个头之后结束。注意,我们在上面的代码段中用{blank_line}标记了空白行;在实际的消息中{blank_line}用空白行替换。

然后,客户端的计算机使用 Internet 将此消息发送到https://httpbin.orgWeb 服务器。服务器处理请求,并发送以下响应:

HTTP/1.1 200 OK
Connection: keep-alive
Server: meinheld/0.6.1
Date: Wed, 11 Apr 2018 18:15:03 GMT
{blank_line}

响应的第一行说明请求已成功完成。下面的三行组成了 HTTP 响应头,这是服务器发送回客户机的可选信息。最后,消息结束时的空白行告诉客户端服务器已完成发送响应头,然后将发送响应体:

<html>
  <body>
    <h1>Herman Melville - Moby-Dick</h1>
    <p>
      Availing himself of the mild...
    </p>
  </body>
</html>

几乎每一个与互联网交互的应用程序都使用这个 HTTP 协议。例如,在您的 Web 浏览器中访问https://httpbin.org/html 会发出与上面的curl命令相同的基本 HTTP 请求。您的浏览器没有像上面那样将响应显示为纯文本,而是识别出文本是一个 HTML 文档,并将相应地显示它。

实际上,我们不会以文本形式写出完整的 HTTP 请求。相反,我们使用像curl或 Python 库这样的工具来构造请求。

Python中

Python requests库允许我们用 Python 发出 HTTP 请求。下面的代码发出的 HTTP 请求与运行curl -v https://httpbin.org/html相同。

import requests

url = "https://httpbin.org/html"
response = requests.get(url)
response
<Response [200]>

请求

让我们仔细看看我们提出的请求。我们可以使用response对象访问原始请求;我们在下面显示请求的 HTTP 头:

request = response.request
for key in request.headers: # The headers in the response are stored as a dictionary.
    print(f'{key}: {request.headers[key]}')
User-Agent: python-requests/2.12.4
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive

每个 HTTP 请求都有一个类型。在本例中,我们使用了一个从服务器检索信息的GET请求。

request.method
'GET'

响应

让我们检查一下从服务器收到的响应。首先,我们将打印响应的 HTTP 头。

for key in response.headers:
    print(f'{key}: {response.headers[key]}')
Connection: keep-alive
Server: gunicorn/19.7.1
Date: Wed, 25 Apr 2018 18:32:51 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 3741
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
X-Powered-By: Flask
X-Processed-Time: 0
Via: 1.1 vegur

HTTP 响应包含一个状态码,是一个特殊的数字,表示请求是成功还是失败。状态码200表示请求成功。

response.status_code
200

最后,我们显示响应内容的前 100 个字符(整个响应内容太长,无法在这里很好地显示)。

response.text[:100]
'<!DOCTYPE html>\n<html>\n  <head>\n  </head>\n  <body>\n      <h1>Herman Melville - Moby-Dick</h1>\n\n     '

请求类型

我们上面的请求是一个GETHttp 请求。有多种 HTTP 请求类型;最重要的两种是GETPOST请求。

GET 请求

GET请求用于从服务器检索信息。由于您每次在地址栏中输入 URL 时您的 Web 浏览器都会发出GET请求,GET请求是最常见的 HTTP 请求类型。

curl默认使用GET请求,因此运行curl https://www.google.com/会向https://www.google.com/发出GET请求。

POST请求

POST请求用于将信息从客户端发送到服务器。例如,一些网页包含供用户填写的表单,例如登录表单。单击“提交”按钮后,大多数 Web 浏览器都会发出一个POST请求,将表单数据发送到服务器进行处理。

让我们来看一个将'sam'作为参数'name'发送的POST请求的例子。这个可以通过在命令行上运行 curl -d 'name=sam' https://httpbin.org/post 来完成。

请注意,这次我们的请求有一个主体(用POST请求的参数填充),响应的内容与之前的GET响应不同。

与 HTTP 头类似,以POST请求发送的数据使用键值格式。在 Python 中,我们可以通过使用requests.post并将字典作为参数传入来发出POST请求。

post_response = requests.post("https://httpbin.org/post",
                              data={'name': 'sam'})
post_response
<Response [200]>

服务器将用状态码响应,以表示POST请求是否成功完成。此外,服务器通常会发送一个响应主体来显示给客户机。

post_response.status_code
200
post_response.text
'{\n  "args": {}, \n  "data": "", \n  "files": {}, \n  "form": {\n    "name": "sam"\n  }, \n  "headers": {\n    "Accept": "*/*", \n    "Accept-Encoding": "gzip, deflate", \n    "Connection": "close", \n    "Content-Length": "8", \n    "Content-Type": "application/x-www-form-urlencoded", \n    "Host": "httpbin.org", \n    "User-Agent": "python-requests/2.12.4"\n  }, \n  "json": null, \n  "origin": "136.152.143.72", \n  "url": "https://httpbin.org/post"\n}\n'

响应状态码类型

先前的 HTTP 响应的 HTTP 状态码为200。此状态码表示请求已成功完成。还有数百个其他的 HTTP 状态码。谢天谢地,它们被分为不同的类别,以便于记忆:

  • 100s-信息:需要更多来自客户端或服务器的输入 (例如 100 Continue(继续)、102 Processing(处理中))
  • 200S-成功:客户端请求成功 (例如 200 OK(成功),202 Accepted(已接受))
  • 300s-重定向:请求的 URL 位于其他位置;可能需要用户的进一步操作 (例如,300 Multiple Choices(多个选项),301 Moved Permanently(永久移动))
  • 400s-客户端错误:客户端错误 (例如 400 Bad Request(错误请求),403 Forbidden(禁止),404 Not Found(未找到))
  • 500s-服务器错误:服务器端错误或服务器无法执行请求 (例如,500 Internal Server Error(内部服务器错误),503 Service Unavailable(服务不可用))

我们可以看看其中一些错误的例子。

# This page doesn't exist, so we get a 404 page not found error
url = "https://www.youtube.com/404errorwow"
errorResponse = requests.get(url)
print(errorResponse)
<Response [404]>
# This specific page results in a 500 server error
url = "https://httpstat.us/500"
serverResponse = requests.get(url)
print(serverResponse)
<Response [500]>

摘要

我们介绍了 HTTP 协议,这是使用 Web 的应用程序的基本通信方法。尽管协议指定了一种特定的文本格式,但我们通常使用其他工具来为我们发出 HTTP 请求,例如命令行工具curl和 Python 库requests