浏览器向服务器请求一张图片,到底发生了什么?

本文说明了http协议传输图片的交互数据的过程和测试方法。

动因

学习编程,其实不在于编程本身。千万不要满足于会调用现成的函数。很多人都知道,通过浏览器访问一张图片链接,服务器就会返回图片,于是浏览器就月显示出来。真那么简单么,细节是什么?为了从零开始实现服务器与浏览器的交互,我们必须去了解http协议,然后才是编程实现。

了解http协议的方法是:

(1)阅读协议本身。

(2)通过实验观察别人已经实现的协议的工作过程。

一般,读协议本身是必要的,但只靠”读“并不能真正了解协议本身。有一句话说得好:衡量你是否真正理解一个原理,在于你是否使用程序实现了这个原理,你要懂,就要让计算机先懂。通过实验能看到通信协议工作的活生生的过程,是理解通信协议最好的办法。记住,你永远不可能在岸上学会游泳!

http协议是一种基于文本的应用层传输协议,我们可以通过一些协议分析工具来观察信息的传输过程。

HTTPWATCH

我在这里选用了一款强大的网页数据分析工具HttpWatch 。安装了HttpWatch后, 将集成在Internet Explorer中,能够收集并显示浏览器与服务器交互过程的底层信息。能够在显示网页同时显示网页请求和回应的日志信息。甚至可以显示浏览器缓存和IE之间的交换信息。集成在Internet Explorer工具栏。

图为安装后,打开IE浏览器的应用界面。
在这里插入图片描述

我们就用HttpWatch来分析浏览器和web服务器之间的交互消息吧。

用IE访问服务器端的一张png图片

讲用http协议访问文本的例子网上很多,如我在”VC++6.0下用60行程序写成一个最简单的WEB服务器“一文中已描述的。 为了实现自己编写的服务器程序能返回图片数据,就必须了解成熟的web服务器(如IIS,Apache,Tomecat等)是如何处理图片数据请求并作出响应的。

可以用任意网站上的图片链接作为测试实验对象。例如,我以

http://www.wtclab.net/newwtc/assets/images/teachers/shaoyubin.jpg

作为访问对象。

安装好HTTPWATCH后,打开IE浏览器(Win10下,IE11),鼠标右键可调出HTTPWATCH应用界面。如上图示。

(1)如果上一次用过,可能有缓存,可用HTTPWATCH的Tools菜单清除之,以保证与我的实验结果相同。

在这里插入图片描述

(2)连接上互联网,调出HTTPWATCH应用界面并清除缓存后,点击菜单项上的Record 进行数据记录。

(3)在浏览器地址栏输入链接地址并回车。

将发现浏览器中显示出照片,同时HTTPWATCH应用界面中会给出交互数据来。如下:

在这里插入图片描述

(4)完成数据记录后,点击stop 停止记录。采用Export工具可将数据导出为文本格式。例如,将浏览器请求数据导出为shaoyubin.jpg.request.txt,而将服务器响应数据导出为shaoyubin.jpg.response.txt.

观察数据

浏览器请求数据 shaoyubin.jpg.request.txt的内容是:

GET /newwtc/assets/images/teachers/shaoyubin.jpg HTTP/1.1
Accept: text/html, application/xhtml+xml, image/jxr, */*
X-HttpWatch-RID: 70513-10228
Accept-Language: zh-Hans-CN,zh-Hans;q=0.8,en-US;q=0.5,en;q=0.3
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko
Accept-Encoding: gzip, deflate
Host: www.wtclab.net
Connection: Keep-Alive


其中,第一行说明了要请求的资源位置和使用HTTP的版本。其他行含义参见HTTP协议描述,这里不过多解释。总之是告诉服务器:我是谁(User-Agent),我能接收哪些格式的消息(Accept,Accept-Language,Accept-Encoding),要请求服务器做什么(GET),完成后是否保持连接(Connection)等等。

服务器收到如上消息后,返回响应为shaoyubin.jpg.response.txt。可用notepad++ 编辑器打开。如下图示:

在这里插入图片描述

以16进制显示为:
在这里插入图片描述

可见返回消息中,既有文本形式的http报文头,又有纯二进制图片数据。http报文头以两个空行(0d 0a 0d 0a)为结束标志,之后的报文数据(对于图片,就是图片文件的二进制流)。

HTTP报文头为:

HTTP/1.1 200 OK
Content-Type: image/jpeg
Last-Modified: Fri, 23 Jun 2017 02:47:38 GMT
Accept-Ranges: bytes
ETag: "7a849613cbebd21:0"
Server: Microsoft-IIS/7.0
X-Powered-By: ASP.NET
Date: Wed, 31 Oct 2018 13:54:28 GMT
Content-Length: 36993

第一行表示服务器能正确响应。
第二行说明了返回消息的类型为image/jpeg,以便浏览器能调用相应要方法解析并显示出来。最末行(9行)说明了图片文件的大小字节数。其他行分别说明了服务器的身份(IIS 7),资源最后修改日期,当前时间等等,详细解释搜索百度相应词字即可。

在notepad++中,小心地将前10行删掉,即只剩下纯数据部分,将之另存为如sybrecvdat.jpg,这时将得到一个完整的jpg文件,查看大小,正好是Content-Length: 36993 字节。

在这里插入图片描述

这就验证了回传数据的确是完整的二进制流。

结论

所以, 要自己实现能回传图片的服务器,只需依照如上协议回传正确的http头后,接着传输相应文件的二进制流即可。

本文说明了http协议传输图片的交互数据的过程和测试方法。

猜你喜欢

转载自blog.csdn.net/shaoyubin999/article/details/83590764