一、探索之旅从输入网址开始
我们在浏览器地址栏输入的网址叫“URL”(Uniform Resourse Locator),统一资源定位符
URL 的各种格式
# 用HTTP协议访问Web服务器时
http://user:password@www.glasscom.com:80/dir/file1.htm
用户名 密码 Web服务器域名 端口号 文件的路径名
(可省略)(可省略) (可省略)
# FTP协议下载和上传文件时
ftp://user:password@ftp.glasscom.com:21/dir/file1.htm
用户名 密码 FTP服务器域名 端口号 文件的路径名
(可省略)(可省略) (可省略)\
# 读取客户端计算机本地文件时
file://localhost/c:/path/file1.zip
计算机名 文件的路径名
(可省略)
# 发送电子邮件
mailto:tone@glasscom.com
邮件地址
URL 有不同的写法,但有一个共同点,那就是 URL 开头的文字,即 http:
、ftp:
、file:
、mailto:
,它们表示浏览器应当使用的访问方法。
二、浏览器先要解析 URL
对 URL 进行元素拆解
「http:」+「//」+「Web服务器域名」+「/」+「目录名」+「/」+...+「文件名」
URL开头表示访问数据源的机制,也就是协议
"//" 后面的字符串表示服务器的名称
表示数据源(文件)的路径名(可省略)
三、省略文件名的情况
dir/
表示 dir 目录,/
表示根目录http://www.lab.glasscom.com/dir
这个 URL 中文件名被省略了,它会默认访问 index.html
http://www.lab.glasscom.com/
它表示访问服务器的根目录,即 index.html
http://www.lab.glasscom.com
,它连 /
都省略了,代表访问根目录下设置的默认文件,即 index.html
http://www.lab.glasscom.com/whatisthis
,如果服务器上存在名为 whatisthis 的文件,则作为文件处理,如果存在名为 whatisthis 的目录,则作为目录名处理
四、HTTP 请求的基本思路
HTTP 的基本思路
- 客户端向服务器发送请求消息,请求消息中中包含“方法”和“URI”
- URI 全称是 Uniform Resource Identifier,统一资源标识符
- 服务器向客户端发送响应消息,响应消息中包含“状态码”等内容
HTTP 的主要方法
方法 | 含义 |
---|---|
GET | 获取 URI 指定的信息,如果 URI 指定的是文件,则返回文件的内容,如果URI 指定的是 CGI 程序,则返回该程序的输出结果 |
POST | 从客户端向服务器发送数据。一般用于发送表单中填写的数据等情况 |
HEAD | 和 GET 基本相同。不过它只返回 HTTP 的消息头(message header),并不返回数据的内容。用于获取文件最后更新时间等属性信息 |
OPTION | 用于通知或查询通信选项 |
PUT | 替换 URI 指定的服务器上文件。如果 URI 指定的文件不存在,则创建该文件 |
DELETE | 删除 URI 指定的服务器上文件 |
TRACE | 将服务器收到的请求行和请求头部(header)直接返回给客户端。用于在使用代理的环境下检查改写请求的情况 |
CONNECT | 使用代理传输加密消息时使用的方法 |
最常用的是 GET 方法。在 URI 中写上存放网页的文件名 /dir/fie1.html
,当 Web 服务器收到消息后,会打开 /dir1/file1.html
文件并读取出里面的数据,让后将读出的数据存放到响应消息中,并返回客户端。最后客户端浏览器会收到这些数据并显示在屏幕上
还有一个经常使用的是 POST 方法。使用 POST 方法时,URI 会指向 Web 服务器中运行的一个应用程序的文件名,典型的例子包括 index.cgi
、index.php
等,当服务器收到请求后,Web 服务器会将请求消息中的数据发送给 URI 指定的应用程序。最后,Web 服务器从应用程序接收输出的结果,会将它存放到响应消息中并返回给客户端。
五、生成 HTTP 请求消息
HTTP 消息的格式
# 请求消息
<方法> <URI> <HTTP版本> # 请求行
<字段名>:<字段名> # 消息头
...
...
...
<空行>
<消息体> # 消息体
# 响应消息
<HTTP版本> <状态码> <响应短语> # 状态行
<字段名>:<字段名> # 消息头
...
...
...
<空行>
<消息体> # 消息体
HTTP 中主要的头部字段
头部字段类型 | 含义 |
---|---|
通用头:适用于请求和响应消息的头字段 | |
Data | 表示请求和响应生成的日期 |
Pragma | 表示数据是否允许缓存的通信选项 |
Cache-Control | 控制缓存的相关信息 |
Connection | 设置发送响应之后 TCP 连接是否继续保持的通信选项 |
Transfer-Encoding | 表示消息主体的编码格式 |
Via | 记录途中经过的代理和网关 |
请求头:用于表示请求消息的附加信息的头字段 | |
Authorization | 身份认证数据 |
From | 请求发送者的邮箱地址 |
If-Modified-Since | 如果希望仅当数据在某个日期之后有更新时才执行请求,可以在这个字段指定希望日期。一般来说,这个功能的用途在于判断客户端缓存的数据是否已经过期,如果已经过期则获取新的数据 |
Referer | 当通过点击超级链接进入下一个页面时,在这里会记录上一个页面的 URI |
User-Agent | 客户带入软件的名称和版本号等相关信息 |
Accept | 客户端可支持的数据类型(Content-Type),以 MIME 类型来表示 |
Accept-Charset | 客户端可支持的字符集 |
Accept-Encoding | 客户端可支持的编码格式(Content-Encoding),一般来说表示数据的压缩格式 |
Accept-Language | 客户端可支持的语言,汉语为 zh,英语为 en |
Host | 接收请求的服务器 IP 地址和端口号 |
If-Match | 参见 Etag |
If-None-Match | 参见 Etag |
If-Unmodified-Since | 当指定日期之后数据未更新时执行请求 |
Range | 当需要只获取部分数据而不是全部数据时,可通过这个字段指定要获取的数据范围 |
响应头:用于表示响应消息的附加信息的头字段 | |
Location | 表示信息的准确位置。当请求的 URI 为相对路径时,这个字段用来返回绝对路径 |
Server | 服务器程序的名称和版本号等信息 |
WWW-Authenticate | 当请求的信息存在访问控制时,返回身份认证用的数据(Challenge) |
Accept-Ranges | 当希望仅请求部分数据(使用 Range 来指定范围)时,服务器会告知客户端是否支持这一功能 |
实体头:用于表示实体(消息体)的附加信息的头字段 | |
Allow | 表示指定的 URI 支持的方法 |
Content-Encoding | 当消息经过压缩等编码处理时,表示其编码格式 |
Content-Length | 表示消息体的长度 |
Content-Type | 表示消息体的数据类型,以 MIME 规格定义的数据类型来表示 |
Expires | 表示消息体的有效期 |
Last-Modified | 数据的最后更新日期 |
Content-Language | 表示消息体的语言。汉语为 zh,英语为 en |
Content-Location | 表示消息体在服务器上的位置(URI) |
Content-Range | 在更新操作中,有时候需要基于上一次请求的响应数据来发送下一次请求。在这种情况下,这个字段可以用来提供上次响应与下次请求之间的关联信息。上次响应中,服务器会通过 Etag 向客户端发送一个唯一表示,在下次请求中客户端可以通过 If-Match、If-None-Match、If-Range 字段将这个标识告知服务器,这样服务器就知道该请求和上次请求时相关的。这个字段的功能和 Cookie 是相同的,但 Cookie 是网景(Netscape)公司自行开发的规格,而 Etag 是将其标准化后的规格 |
六、发送请求后会收到响应
当我们将上述请求消息发送出去之后,Web 服务器会返回响应消息
在响应消息中,第一行的内容为状态码和响应短语
HTTP 状态码概要(第一位数字表示状态类型,第二、三位数字表示具体情况,下面列举第一位数字的含义)
状态码 | 含义 |
---|---|
1xx | 告知请求的处理进度和情况 |
2xx | 成功 |
3xx | 表示需要进一步操作 |
4xx | 客户端出错 |
5xx | 服务器出错 |
由于每条请求消息中只能写 1 个 URI,所以每次只能获取 1 个文件,如果需要获取多个文件,必须对每个文件单独发送请求。比如 1 个网页中包含 3 张图片,那么获取网页加上获取图片,一共需要向 Web 服务器发送 4 条请求
「@浪里淘沙的小法师」