深入理解HTTP【转载】

出处:深入理解HTTP—Joanna.Yan

先看一个简单的http请求和响应:

1.HTTP协议是什么**?**

图片名称 图片名称

我们浏览的每一个网页都是基于HTTP协议呈现的,HTTP协议是互联网应用中,客户端(浏览器)

与服务器之间进行数据通信的一种协议。协议中规定了客户端应该按照什么格式给服务器发送请求,同时也约定了服务端返回的响应结果应该是什么格式。

只要大家都按照协议规定方式发起请求和返回响应结果,任何人都可以基于HTTP协议实现自己的Web客户端(浏览器、爬虫)和Web服务器(Nginx、Apache等)。

HTTP协议本身是非常简单的。它规定,只能由客户端主动发起请求,服务器接收请求处理后返回响应结果,同时HTTP是一种无状态的协议,协议本身不记录客户端的历史请求记录。

HTTP(超文本传输协议)是一个基于请求与响应模式的、无状态的、应用层的协议,常基于TCP的连接方式。
HTTP协议的主要特点:

1.支持客户端/服务器模式;

2.简单快速:客户向服务器请求服务时,只需传送请求方法和路径。由于HTTP协议简单,通信速度很快。

3.灵活:HTTP允许传输任意类型的数据对象。类型由Content-Type加以标记。

4.无连接:即每次连接只处理一个请求,处理完毕客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。

5.无状态:无状态是指协议对于事务处理没有记忆能力。

HTTP1.0协议默认的是非持久连接,HTTP1.1默认的连接方式为持久连接。

非持久连接:每次服务器发出一个对象后,相应的TCP连接就被关闭,也就是说每个连接都没有持续到可用于传送其他对象。每个TCP连接只用于传输一个请求和一个响应消息。

持久连接:服务器在发出响应后让TCP连接继续打开着。同一对客户/服务器之间的后续请求和响应可以通过这个连接发送。HTTP/1.1的默认模式使用带流水线的持久连接。

HTTP协议是如何规定请求格式和响应格式的呢?换言之,客户端按照什么格式才能正确发起HTTP请求呢?服务端按照什么格式返回响应结果客户端才能正确解析?

2.HTTP请求

HTTP请求由3部分组成,分别是请求行、请求首部、请求体,首部和请求体是可选的,并不是每个请求都需要的。

请求行

请求行是每个请求必不可少的部分,它由3部分组成,分别是请求方法(method)、请求URL(URI)、HTTP协议版本,以空格隔开。

HTTP协议中最常用的请求方法有:GET、POST、PUT、DELETE。GET方法用于从服务器获取资源,90%的爬虫都是基于GET请求抓取数据。

请求URL是指资源所在服务器的路径地址,比如上图例子表示客户端想获取index.html这个资源,它的路径在服务器foofish.net的根目录(/)下面。

请求首部

因为请求行所携带的信息量非常有限,以至于客户端还有很多想向服务器要所的事情不得不放在请求首部(Header),请求首部用于给服务器提供一些额外的信息,比如User-Agent用来表示客户端的身份,让服务器知道你是来自浏览器的请求还是爬虫,是来自Chrome浏览器还是FireFox。HTTP/1.1规定了47种首部字段类型。HTTP首部字段的格式很像Python中的字典类型,由键值对组成,中间用冒号隔开。比如:

User-Agent: Mozilla/5.0

因为客户端发送请求时,发送的数据(报文)是由字符串构成的,为了区分请求首部的结尾和请求体的开始,使用一个空行来表示,遇到空行时,就表示这个是首部的结尾,请求体的开始。

请求体

请求体是客户端提交给服务器的真正内容,比如用户登录时的需要用的用户名和密码,比如文件上传的数据,比如注册用户信息时提交的表单信息。

现在我们用Python提供的最原始API socket模块来模拟向服务器发起一个HTTP请求。

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    # 1. 与服务器建立连接
    s.connect(("www.seriot.ch", 80))
    # 2. 构建请求行,请求资源是 index.php
    request_line = b"GET /index.php HTTP/1.1"
    # 3. 构建请求首部,指定主机名
    headers = b"Host: seriot.ch"
    # 4. 用空行标记请求首部的结束位置
    blank_line = b"\r\n"

    # 请求行、首部、空行这3部分内容用换行符分隔,组成一个请求报文字符串
    # 发送给服务器
    message = b"\r\n".join([request_line, headers, blank_line])
    s.send(message)

    # 服务器返回的响应内容稍后进行分析
    response = s.recv(1024)
    print(response)

3.HTTP响应

服务端接收请求并处理后,返回响应内容给客户端,同样地,响应内容也必须遵循固定的格式浏览器才能正确解析。HTTP响应也由3部分组成,分别是:响应行、响应首部、响应体,与HTTP的请求格式是想对象的。

响应行

响应行同意也是3部分组成,由服务端支持的HTTP协议版本号、状态码以及对状态吗的简短原因描述组成。

状态码是响应行中很重要的一个字段。通过状态码,客户端可以知道服务器是否正常处理的请求。如果状态码是200,说明客户端的请求处理成功,如果是500,说明服务器处理的时候出现了异常。404表示请求的资源在服务器找不到。除此之外,HTTP协议还定义了很多其他的状态码。

响应首部

响应首部金额请求首部类似,用于响应内容的补充,在受不里面可以告知客户端响应体的数据类型是什么?响应内容返回的时候是什么时候,响应体是否压缩了,响应体最后一次修改的时间。

响应体

响应体(body)是服务器返回的真正内容。它可以是一个HTML页面,或者是一张图片、一段视频等等。

我们继续沿用前面那个例子来看看服务器返回的响应结果是什么?因为这里只接收了前1024个字节,所以有一部分响应内容是看不到的。
复制代码

b'HTTP/1.1 200 OK\r\n
Date: Tue, 04 Apr 2017 16:22:35 GMT\r\n
Server: Apache\r\n
Expires: Thu, 19 Nov 1981 08:52:00 GMT\r\n
Set-Cookie: PHPSESSID=66bea0a1f7cb572584745f9ce6984b7e; path=/\r\n
Transfer-Encoding: chunked\r\n
Content-Type: text/html; charset=UTF-8\r\n\r\n118d\r\n

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n\n
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n
<head>\n\t
    <meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1" />    \n\t
    <meta http-equiv="content-language" content="en" />\n\t
...
</html>

从结果来看,它与协议中规范的格式是一样的,第一行是响应行,状态码是200,表明请求成功。第二部分是响应首部信息,由多个首部组成,有服务器返回响应的时间,Cookie信息等等。第三部分就是真正的响应体HTML文本。

Java中平时我们访问网络经常会用到:
4.HttpURLConnection和HttpClient

在JDK的java.NET包中已经提供了访问HTTP协议的基本功能:HttpURLConnection。

但是对于大部分应用程序来说,JDK库本身提供的功能还不够丰富和灵活。

除此之外,在Android中,androidSDK中集成了Apache的HttpClient模块,用来提供高效的、最新的、功能丰富的支持HTTP协议工具包,并且它支持HTTP协议最新的版本和建议。使用HttpClient可以快速开发出功能强大的Http程序。

区别:

HttpClient是个很不错的开源框架,封装了访问http的请求头、参数、内容体、响应等等。

HttpURLConnection是Java的标准类,什么都没封装,用起来太原始,不方便,比如重访问的自定义以及一些高级功能等。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值