2.2 HTTP
HTTP,即超文本传输协议,是Internet上最主要的Web应用层标准。B/S架构的应用系统用HTTP在客户端与服务器之间传送数据。HTTP可以传送任何格式的数据,从文本到图像甚至视频流都可以通过HTTP进行传输。本节讲解进行网络开发所必需的HTTP知识。
2.2.1 HTTP流程
HTTP是Web浏览器与Web服务器之间通信的标准协议,是Internet上能够可靠地交换文件的重要基础。HTTP的基本交互流程如图2.4所示。
图2.4 HTTP的基本交互流程
每个HTTP站点都有一个服务器进程监听着TCP的HTTP端口,HTTP端口默认为80,也可由服务器进程设置为其他端口。当服务器发现有客户端建立连接并提交了一个 HTTP 请求(Request)后,就根据请求的内容执行相应的操作,并将结果返回给客户端(Response)。通常客户在浏览器中发起一次网络访问的步骤如下。
(1)输入网址并按Enter键,比如访问http://mysite:8080/app/index.html。
(2)浏览器通过域名系统查询mysite的真实IP,比如212.34.98.20。
(3)向服务器212.34.98.20的8080端口发起TCP连接请求并建立连接。
(4)发送HTTP请求的内容,包括访问的地址/app/index.html、访问方式GET、浏览器本身的产品名等。
(5)服务器返回/app/index.html中的数据作为Response发送给客户端。如果请求的不是一个文件,则服务器需要执行相应的代码,动态生成且返回给客户端。
(6)浏览器接收到结果后关闭与服务器的TCP连接。
(7)浏览器将接收到的结果呈现在显示器上。
注意:域名解析本身不是HTTP的一部分,客户端应在向服务器建立TCP连接之前就通过DNS服务器完成域名解析工作。
以上是最典型的HTTP流程,当今的HTTP版本还允许客户端在一次HTTP请求完成后不关闭TCP连接,以便第2次发送HTTP请求时复用该连接,从而达到减少系统整体开销的目的,此技术在HTTP中叫作keep-alive。
2.2.2 HTTP消息结构
Python网络开发者必须通过直接或间接的方式与HTTP打交道。通过学习HTTP消息结构,可以让开发人员更好地理解Python Web框架中的各种配置及开发选项。
1.Request消息结构
HTTP的两种消息(Request和Response)采用不同的消息结构,Request的格式如下:
结构格式由两部分组成:消息头(HTTP HEAD)、消息体(HTTP BODY)。消息头必须遵循上述格式,头字段可以有若干个;消息体则没有固定格式;HEAD与BODY之间以一个空行分隔。上述格式中的请求方法、URL、协议版本、头字段等都属于消息头。常用的消息体格式包括HTML、XML、JSON等。典型的Request消息如下:
本例是一个用GET方法访问URL http://www.mysite.com/hello.txt 页面的请求头,向服务器声明使用HTTP1.1版本,并通过Accept-Language标识了客户端接收的消息语言。本例的Request中没有消息体。
2.Response消息结构
Response是服务器根据客户端的请求包做相应处理后向客户端返回的结果,Response的格式如下:
消息结构仍然由两部分组成,与Request的不同点是第1行由协议版本和错误码组成。典型的Response消息如下:
本例中返回了一个HTTP 1.1版本的消息,错误代码为200,错误字符串为OK。之后的一系列头字段标识了当前的时间、服务器的应用程序名、消息类型、消息体的长度等。消息体是一个HTML包。
3.常用头字段
HTTP头字段以键值对的方式为服务器或客户端提供对方的信息,比如之前用到的Accept-Language、Server等。HTTP中有一些预定义的头字段经常被用到,有经验的开发者需要熟记这些,如表2.2所示。表中的“方向”列,如果是Response则指示从服务器发送给客户端,如果是Request则指示从客户端发送给服务器,Both表示两个方向皆可。
表2.2 常用的HTTP头字段
续表
续表
4.常用错误代码
前面已经学习了HTTP,每个Response的第1行中有一个整数状态码用于表达其对应Request的结果。HTTP除了约定了该状态的表达方式,还约定了该状态的取值范围,约定的5类状态码如下。
· 1xx:信息;表明服务器已经收到Request,但需要进一步处理,请客户端等待。
· 2xx:成功;处理成功。
· 3xx:重定向;请求的地址已被重定向,需要客户端重新发起请求。
· 4xx:客户端错误;请求中提交的参数或内容有错误。
· 5xx:服务器错误;服务器处理请求时出错,一般本类错误需要联系服务器管理员处理。
注意:1xx~5xx的错误为HTTP标准错误,在网站开发中如需定义自己的错误代码,则需要避开该范围。
在上述5类错误中,常见的HTTP错误代码如表2.3所示。
表2.3 常见的HTTP错误代码
2.2.3 HTTP请求方法
通过上面的学习,读者一定想知道HTTP Request包的第1个参数“请求方法”到底有哪些取值及为什么要区分它们。HTTP访问方式的意义在于它能够告诉服务器客户端访问URL的目的是什么,是获取信息、上传数据,还是删除信息等。表2.4总结了HTTP 1.1中常用的访问方式及其意义。
表2.4 HTTP1.1中常用的访问方式及其意义
2.2.4 基于HTTP的网站开发
经过几十年的发展,已经出现几个成熟的处理HTTP的知名Web服务器。这些Web服务器可以解析(handle)HTTP,当Web服务器接收到一个HTTP请求时,会根据配置的内容返回一个静态HTML页面或者调用某些代码动态生成返回结果。Web服务器把动态响应(dynamic response)产生的委托(delegate)给其他一些程序,例如Python代码、JSP(JavaServer Pages)脚本、Servlets、ASP(Active Server Pages)脚本等。无论它们的目的如何,这些服务器端(server-side)的程序通常会产生一个HTTP响应让浏览器浏览。
由于目标操作系统、应用场景及商业目的的不同,当今主流的Web服务器各有特色,将它们的特性简单地概括如下。
· Apache:是世界上用得最多的Web服务器,市场占有率达60%左右。由于其卓越的性能,Tomcat或JBoss等很多其他Web服务器使用Apache为自己提供HTTP接口服务。
· Nginx:是一款轻量级、高性能的HTTP和反向代理服务器。因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。
· IIS:微软的Web服务器产品。由于Windows的影响,IIS是目前最流行的Web服务器产品之一,它的最大优势当然是对微软ASP.net及其周围产品的支持。
· Tomcat:是一个开源服务器,是Java Servlet 2.2和JavaServer Pages 1.1技术的标准实现。
· JBoss:是一个管理EJB的容器和服务器,支持EJB 1.1、EJB 2.0和EJB 3的规范。但JBoss的核心服务不包括支持Servlet、JSP的Web容器,一般与Tomcat或Jetty绑定使用。
当前的主流Web服务器都实现了主流语言的可调用接口标准,这些标准如下。
· CGI:Common Gateway Interface,CGI规范允许Web服务器执行外部程序,并将它们的输出发送给Web浏览器,CGI将Web的一组简单的静态超媒体文档变成一个完整的新的交互式媒体。
· ISAPI:Internet Server Application Program Interface,是微软提供的一套面向Web服务的API接口,它能实现CGI提供的全部功能,并在此基础上进行了扩展,例如提供了过滤器应用程序的接口。
· WSGI:Web Server Gateway Interface,是一套专为Python语言制定的网络服务器标准接口。本书将要学习的Python Web框架均以WSGI为基础标准。
从客户端浏览器的角度来看,它的每次访问是通过HTTP访问Web服务器从而获得某种服务(下载文件、查看页面、订购商品等)的,但实际上Web服务器仅起到桥梁的作用,即将浏览器的HTTP请求解码,转换成服务器端程序能够识别的接口调用方式,然后将服务器端程序生成的返回封装成HTTP Response,并返回给浏览器。服务器端程序、Web服务器、客户端之间的关系如图2.5所示。
图2.5 服务器端程序
最简单的服务器端程序可以是直接读取某文件或返回固定的网页内容;稍复杂一些的服务器端程序需要处理客户端通过HTTP、URL、HTML中传入的参数、动态执行逻辑代码、在数据库或缓存中读写数据等一系列操作,才能最终生成调用结果。