HTTP和TCL
WEB:一个海量分布式客户端/f服务器信息系统
HTTP:是一个不堆成的请求-相应客户端-服务器协议。HTTP客户端向HTTP服务器发送请求消息,服务器反过来响应消息。换句话说,HTTP是一种拉协议,客户机拉动从所属服务器信息(而不是服务器推送信息到客户端)
HTTP特点:1.无状态;2,允许协商数据类型和表示形式; 3, 是分布式协作超媒体信息系统的应用级协议,可用于超出超文本用途的许多任务;
浏览器: 浏览器将URL请求转换为请求消息并将其发送到HTTP服务器。HTTP服务器解释请求消息,并返回一个适当的响应消息。
URL: 统一资源定位符,用于唯一标识网络上的资源 eg: 协议://主机名:端口 / 路径和文件名
网址中有4个部分:
- 协议:客户端和服务器使用的应用层协议,例如HTTP,FTP和Telnet。
- 主机名:服务器的DNS域名(例如
www.nowhere123.com
)或IP地址(例如192.128.1.2)。 - 端口:服务器正在侦听来自客户端的传入请求的TCP端口号。
- 路径和文件名:在服务器文档基础目录下的请求资源的名称和位置。
HTTP协议
当此请求消息到达服务器时,服务器可以采取以下任一操作:
- 服务器会把接收到的请求,该请求映射到文件服务器的文件目录下,并返回请求的客户端的文件。
- 所述服务器解释接收到的请求,所述请求为映射程序保存在服务器上,执行该程序,并且该程序的输出返回到客户端。
- 请求不能满足,服务器返回错误消息。
HTTP响应消息的示例如下所示:
HTTP / 1.1 200 OK 日期:Sun,18 Oct 2009 08:56:53 GMT 服务器:Apache / 2.2.14(Win32) Last-Modified:星期六,2004年11月20日07:16:26 GMT ETag:“10000000565a5-2c-3e94b66c2e680” 接受范围:字节 内容长度:44 连接:关闭 内容类型:text / html X-Pad:避免浏览器错误 <html> <body> <h1> It works!</ h1> </ body> </ html>
浏览器收到响应消息,解释消息并根据响应的媒体类型(如Content-Type响应头中)在浏览器窗口中显示消息的内容。常见的媒体类型包括“ text/plain
”,“ text/html
”,“ image/gif
”,“ image/jpeg
”,“ audio/mpeg
”,“ video/mpeg
”,“ application/msword
”和“ application/pdf
”。
在闲置状态下,HTTP服务器只会侦听传入请求配置中指定的IP地址和端口。当请求到达时,服务器分析消息头,应用在配置中指定的规则,并采取适当的操作。网站管理员对网络服务器操作的主要控制是通过配置进行的,后面将详细介绍这些配置。
HTTP over TCP / IP
HTTP是客户端服务器应用程序级别的协议。如图所示,它通常运行在TCP / IP连接上。(HTTP不需要在TCP / IP上运行,它只能假定可靠的传输,任何提供这种保证的传输协议都可以使用。)
TCP / IP(传输控制协议/互联网协议)是一组传输和网络层协议,用于机器在网络上相互通信。
IP(Internet Protocol)是网络层协议,用于处理网络寻址和路由。在IP网络中,每台计算机都分配一个唯一的IP地址(例如,165.1.2.3),IP软件负责将消息从源IP路由到目标IP。在IPv4(IP版本4)中,IP地址由4个字节组成,每个字节的范围是从0到255,用点分隔,称为四点形式。该编号方案支持网络上最多4G的地址。最新的IPv6(IP版本6)支持更多地址。由于记忆数字对大多数人来说都很困难,所以英文域名如www.nowhere123.com
被用来代替。DNS(域名服务)将域名转换为IP地址(通过分布式查找表)。一个特殊的IP地址127.0.0.1总是指您自己的机器。它的命名是“ localhost
”,可用于本地环回测试。
TCP(传输控制协议)是一种传输层协议,负责在两台机器之间建立连接。TCP由2个协议组成:TCP和UDP(用户数据报包)。TCP是可靠的,每个数据包都有一个序列号,并且预计会有确认。如果数据包未被接收器接收到,数据包将被重新传输。数据包传输在TCP中得到保证。UDP不保证数据包传输,因此不可靠。但是,UDP的网络开销较小,可用于视频和音频流等应用,可靠性并不重要。
TCP 在IP机器中复用应用程序。对于每台IP机器,TCP支持(多路复用)多达65536个端口(或套接字),端口号为0到65535.应用程序(如HTTP或FTP)在传入请求的特定端口号上运行(或侦听)。端口0到1023被预先分配到流行的协议,例如,在80处的HTTP,在21的FTP,在23的Telnet,在25的SMTP,在119的NNTP和在53的DNS。端口1024和以上对于用户是可用的。
尽管TCP端口80已预先分配给HTTP,但是作为默认HTTP端口号,这并不禁止您在其他用户分配的端口号(1024-65535)(如8000,8080)上运行HTTP服务器,特别是对于测试服务器。您也可以在同一台计算机上的不同端口号上运行多个HTTP服务器。当客户端发出URL而没有明确说明端口号时,例如,http://www.nowhere123.com/docs/index.html
浏览器将连接到主机的默认端口号80 www.nowhere123.com
。您需要明确指定URL中的端口号,例如,http://www.nowhere123.com:8000/docs/index.html
如果服务器正在监听端口8000而不是默认端口80。
简而言之,要通过TCP / IP进行通信,您需要知道(a)IP地址或主机名,(b)端口号。
HTTP规范
HTTP / 1.0没有解决代理,缓存,持久连接,虚拟主机和范围下载的问题。这些功能在HTTP / 1.1(1999)(RFC 2616中定义)中提供。
HTTP客户端和服务器通过发送文本消息进行通信 客户端向服务器发送请求消息。服务器反过来返回响应消息。
一个HTTP消息由一个消息头和一个可选的消息体组成,由一个空行分隔,如下所示:
HTTP请求消息
HTTP请求消息的格式如下:
请求线
标题的第一行称为请求行,后跟可选的请求标题。
请求行具有以下语法:
request-method-name request-URI HTTP-version
- request-method-name:HTTP协议定义了一组请求方法,例如GET,POST,HEAD和OPTIONS。客户端可以使用这些方法之一向服务器发送请求。
- request-URI:指定请求的资源。
- HTTP版本:目前使用两个版本:HTTP / 1.0和HTTP / 1.1。
请求行的例子是:
GET /test.html HTTP / 1.1 HEAD /query.html HTTP / 1.0 POST /index.html HTTP / 1.1
请求标题
请求头以对的形式name:value
。可以指定多个值,用逗号分隔。
request-header-name:request-header-value1,request-header-value2,...
请求标头的例子是:
主持人:www.xyz.com 连接:保持活跃 接受:image / gif,image / jpeg,* / * Accept-Language:us-en,fr,cn
例
以下显示了一个示例HTTP请求消息:
HTTP响应消息
HTTP响应消息的格式如下所示:
状态行
第一行称为状态行,后面跟随可选的响应标题。
状态行具有以下语法:
HTTP版本 状态码 原因短语
- HTTP版本:此会话中使用的HTTP版本。HTTP / 1.0和HTTP / 1.1。
- 状态码:由服务器生成的一个3位数字,用于反映请求的结果。
- 原因短语:对状态码给出一个简短的解释。
- 常见状态码和原因词组为“200 OK”,“404 Not Found”,“403 Forbidden”,“500 Internal Server Error”。
状态行的例子是:
HTTP / 1.1 200 OK HTTP / 1.0 404未找到 HTTP / 1.1 403禁止
响应头
响应标题的格式为name:value
:
response-header-name:response-header-value1,response-header-value2,...
响应标题的例子是:
内容类型:text / html 内容长度:35 连接:保持活跃 Keep-Alive:超时= 15,最大= 100
响应消息主体包含请求的资源数据。
例
以下显示了一个示例响应消息:
HTTP请求方法
HTTP协议定义了一组请求方法。客户端可以使用这些请求方法之一向HTTP服务器发送请求消息。方法是:
- GET:客户端可以使用GET请求从服务器获取Web资源。
- HEAD:客户端可以使用HEAD请求获取GET请求获取的头。由于标题包含数据的最后修改日期,因此可用于检查本地缓存副本。
- POST:用于将数据发布到Web服务器。
- PUT:请求服务器存储数据。
- 删除:请求服务器删除数据。
- 跟踪:请求服务器返回所需操作的诊断跟踪。
- 选项:请求服务器返回它支持的请求方法列表。
- CONNECT:用于告诉代理与另一个主机建立连接,并简单地回复内容,而不尝试解析或缓存它。这通常用于通过代理进行SSL连接。
- 其他扩展方法。
“GET”请求方法
GET是最常见的HTTP请求方法。客户端可以使用GET请求方法从HTTP服务器请求(或“获取”)一段资源。GET请求消息采用以下语法:
GET 请求 - URI HTTP版本 (可选请求标头) (空白行) (可选请求主体)
- 关键字GET区分大小写,并且必须大写。
- request-URI:指定请求的资源路径,它必须从
/
文档基目录的根目录“ ” 开始。 - HTTP版本:HTTP / 1.0或HTTP / 1.1。该客户端协商用于当前会话的协议。例如,客户端可能会请求使用HTTP / 1.1。如果服务器不支持HTTP / 1.1,它可能会通知客户端使用HTTP / 1.0的响应。
- 客户端使用可选的请求头(例如
Accept
,Accept-Language
等)与服务器进行协商,并要求服务器提供首选内容(例如,使用客户端首选的语言)。 - GET请求消息有一个可选的请求主体,它包含查询字符串(稍后解释)。
测试HTTP请求
有很多方法可以测试HTTP请求。您可以使用实用程序(如“ telnet
”或“ hyperterm
”(在下面搜索“ telnet.exe
”或“ hypertrm.exe
” c:\windows
),或者编写自己的网络程序将原始请求消息发送到HTTP服务器以测试各种HTTP请求。
远程登录
“Telnet”是一个非常有用的网络工具。您可以使用telnet与服务器建立TCP连接; 并发出原始的HTTP请求。例如,假设您已经在端口8000的localhost(IP地址127.0.0.1)中启动了HTTP服务器:
> telnet telnet> help ... telnet帮助菜单 ... telnet> 打开127.0.0.1 8000 连接到127.0.0.1 ... GET /index.html HTTP / 1.0 (点击输入两次发送终止空行 ...) ... HTTP响应消息 ...
Telnet是基于字符的协议。您在telnet客户端上输入的每个字符都会立即发送到服务器。因此,在输入raw命令时不能出现拼写错误,因为删除和退格将发送到服务器。您可能必须启用“本地回显”选项才能看到您输入的字符。查看telnet手册(搜索Windows的帮助)以获取有关使用telnet的详细信息。
网络计划
您也可以编写自己的网络程序来向HTTP服务器发出原始HTTP请求。您的网络程序应首先与服务器建立TCP / IP连接。一旦建立了TCP连接,就可以发出原始请求。
以Java编写的网络程序示例如图所示(假设HTTP服务器在端口8000上的本地主机(IP地址127.0.0.1)上运行):
import java.net。*; import java.io. *; 公共类HttpClient { public static void main(String [] args)throws IOException { //要连接的主机和端口。 String host =“127.0.0.1”; int port = 8000; //创建一个TCP套接字并连接到主机:端口。 Socket socket = new Socket(host,port); //为网络套接字创建输入和输出流。 BufferedReader中 =新的BufferedReader( new InputStreamReader(socket.getInputStream())); PrintWriter出来 = new PrintWriter(socket.getOutputStream(),true); //发送请求到HTTP服务器。 out.println(“ GET /index.html HTTP / 1.0 ”); 通过out.println(); //空白行分隔标题和正文 了out.flush(); //读取响应并在控制台上显示。 字符串行; //如果服务器关闭网络套接字,则readLine()返回null。 while((line = in.readLine())!= null){ 的System.out.println(线); } //关闭I / O流。 附寄(); out.close(); } }
HTTP / 1.0 GET请求
下面显示了HTTP / 1.0 GET请求的响应(通过telnet或您自己的网络程序发出 - 假设您已启动了您的HTTP服务器):
GET /index.html HTTP / 1.0 (输入两次以创建空行)
HTTP / 1.1 200 OK 日期:Sun,18 Oct 2009 08:56:53 GMT 服务器:Apache / 2.2.14(Win32) Last-Modified:星期六,2004年11月20日07:16:26 GMT ETag:“10000000565a5-2c-3e94b66c2e680” 接受范围:字节 内容长度:44 连接:关闭 内容类型:text / html X-Pad:避免浏览器错误 <html> <body> <h1> It works!</ h1> </ body> </ html> 连接到主机丢失。
在这个例子中,客户端发出一个GET请求来请求一个名为“ /index.html
” 的文档; 并协商使用HTTP / 1.0协议。请求标题后需要一个空行。此请求消息不包含正文。
服务器接收请求消息,将请求URI解释并映射到其文档目录下的文档。如果请求的文档可用,服务器将返回文档,其响应状态码为“200 OK”。响应标头提供了返回文档的必要描述,例如最后修改的date(Last-Modified
),MIME类型(Content-Type
)和文档的长度(Content-Length
)。响应主体包含请求的文档。浏览器将根据其媒体类型(例如纯文本,HTML,JPEG,GIF等)以及从响应头中获取的其他信息来格式化和显示文档。
笔记:
- 请求方法名称“GET”区分大小写,并且必须大写。
- 如果请求方法名称拼写错误,服务器将返回错误消息“501方法未实现”。
- 如果请求方法名称不被允许,服务器将返回一条错误消息“405方法不允许”。例如,DELETE是一个有效的方法名称,但可能不被服务器允许(或实现)。
- 如果request-URI不存在,服务器将返回一条错误消息“404 Not Found”。您必须从文档根“ ” 开始发出适当的请求URI
/
。否则,服务器将返回错误消息“400错误请求”。 - 如果HTTP版本丢失或不正确,服务器将返回错误消息“400错误请求”。
- 在HTTP / 1.0中,默认情况下,服务器在传递响应后关闭TCP连接。如果使用telnet连接到服务器,则在收到响应主体后立即出现消息“Connection to host lost”。您可以使用可选的请求标头“
Connection: Keep-Alive
”来请求持久(或keep-alive
)连接,以便可以通过同一个TCP连接发送另一个请求以实现更好的网络效率。另一方面,HTTP / 1.1默认使用保持连接。
响应状态码
响应消息的第一行(即状态行)包含响应状态码,由服务器生成以指示请求的结果。
状态代码是一个3位数字:
- 1xx(信息):收到请求,服务器正在继续该过程。
- 2xx(成功):请求已成功收到,理解,接受和服务。
- 3xx(重定向):必须采取进一步行动才能完成请求。
- 4xx(客户端错误):请求包含错误的语法或无法理解。
- 5xx(服务器错误):服务器无法完成一个明显有效的请求。
一些常见的状态码是:
- 100继续:服务器收到请求并正在提供响应。
- 200 OK:请求已完成。
- 301永久移动:请求的资源已永久移动到新位置。新位置的URL在响应标题中给出
Location
。客户应该向新位置发出新请求。应用程序应更新对此新位置的所有引用。 - 302找到并重定向(或暂时移动):与301相同,但新位置是暂时性的。客户端应该发出新的请求,但应用程序不需要更新引用。
- 304未修改:为了响应
If-Modified-Since
条件GET请求,服务器通知请求的资源未被修改。 - 400错误请求:服务器无法解释或理解请求,可能是请求消息中的语法错误。
- 401需要身份验证:请求的资源受到保护,并且需要客户端的凭证(用户名/密码)。客户端应该用他的凭证(用户名/密码)重新提交请求。
- 403禁止:服务器拒绝提供资源,而不管客户端的身份。
- 404未找到:在服务器中找不到请求的资源。
- 405不允许的方法:使用的请求方法,例如POST,PUT,DELETE是一种有效的方法。但是,服务器不允许该方法用于请求的资源。
- 408请求超时:
- 414请求URI太大:
- 500内部服务器错误:服务器很混乱,通常是由响应请求的服务器端程序中的错误引起的。
- 501方法未实现:使用的请求方法无效(可能是由于输入错误引起的,例如,“GET”拼写错误为“Get”)。
- 502错误网关:代理或网关指示它收到来自上游服务器的错误响应。
- 503服务不可用:由于过载或维护服务器无法响应。客户可以稍后再试。
- 504网关超时:代理或网关指示它收到来自上游服务器的超时。
更多HTTP / 1.0 GET请求示例
示例:Misspelt请求方法
在请求中,“GET”被拼写为“get”。服务器返回错误“501方法未实现”。响应头“ Allow
”告诉客户端允许的方法。
get /test.html HTTP / 1.0 (输入两次以创建空行)
HTTP / 1.1 501方法未实现 日期:2009年10月18日(星期日)10:32:05 GMT 服务器:Apache / 2.2.14(Win32) 允许:GET,HEAD,POST,OPTIONS,TRACE 内容长度:215 连接:关闭 内容类型:text / html; 字符集= ISO-8859-1 <!DOCTYPE HTML PUBLIC“ - // IETF // DTD HTML 2.0 // EN”> <HTML> <HEAD> <title> 501方法未实现</ title> </ HEAD> <BODY> 未执行<h1>方法</ h1> <p>转到/index.html不支持。<br /> </ p> </ BODY> </ HTML>
示例:未找到404文件
在这个GET请求中,在服务器的文档目录下找不到请求URL “ /t.html
”。服务器返回错误“404 Not Found”。
GET /t.html HTTP / 1.0 (输入两次以创建空行)
HTTP / 1.1 404未找到 日期:2009年10月18日星期日10:36:20 GMT 服务器:Apache / 2.2.14(Win32) 内容长度:204 连接:关闭 内容类型:text / html; 字符集= ISO-8859-1 <!DOCTYPE HTML PUBLIC“ - // IETF // DTD HTML 2.0 // EN”> <HTML> <HEAD> <title> 404 Not Found </ title> </ HEAD> <BODY> <h1>未找到</ h1> <p>请求的URL /t.html在此服务器上未找到。</ p> </ BODY> </ HTML>
示例:错误的HTTP版本号
在这个GET请求中,HTTP版本拼写错误,导致语法错误。服务器返回错误“404错误请求”。HTTP版本应该是HTTP / 1.0或HTTP / 1.1。
GET /index.html HTTTTTP / 1.0 (输入两次以创建空白行)
HTTP / 1.1 400错误请求 日期:星期日,2004年2月08日01:29:40 GMT 服务器:Apache / 1.3.29(Win32) 连接:关闭 内容类型:text / html; 字符集= ISO-8859-1 <!DOCTYPE HTML PUBLIC“ - // IETF // DTD HTML 2.0 // EN”> <HTML> <HEAD> <TITLE> 400错误请求</ TITLE> </ HEAD> <BODY> <H1>错误请求</ H1> 你的浏览器发出了这个服务器无法理解的请求。<P> 请求行在协议字符串后面包含无效字符。<P> <P> </ BODY> </ HTML>
注意:最新的Apache 2.2.14将忽略此错误并返回状态码为“200 OK”的文档。
示例:错误的请求-URI
在下面的GET请求中,request-URI没有从根“ /
” 开始,导致了“错误的请求”。
GET test.html HTTP / 1.0 (空行)
HTTP / 1.1 400错误请求 日期:2009年10月18日(星期日)10:42:27 GMT 服务器:Apache / 2.2.14(Win32) 内容长度:226 连接:关闭 内容类型:text / html; 字符集= ISO-8859-1 <!DOCTYPE HTML PUBLIC“ - // IETF // DTD HTML 2.0 // EN”> <HTML> <HEAD> <title> 400错误请求</ title> </ HEAD> <BODY> <h1>错误请求</ h1> <p>您的浏览器发送了此服务器无法理解的请求。<br /> </ p> </ BODY> </ HTML>
示例:保持连接
由于错误,对于HTTP / 1.0 GET请求,服务器会在传递响应后关闭TCP连接。你可以通过一个可选的请求头“ Connection: Keep-Alive
” 来请求保持TCP连接(以便使用相同的TCP连接发送另一个请求,以提高网络效率)。服务器包含一个“ Connection: Keep-Alive
”响应头,通知客户端他可以在保持活动超时之前使用此连接发送另一个请求。另一个响应头“ Keep-Alive: timeout=x, max=x
”告诉客户端超时(以秒为单位)以及可以通过这个持久连接发送的最大请求数。
GET /test.html HTTP / 1.0 连接:Keep-Alive (空白行)
HTTP / 1.1 200 OK 日期:Sun,18 Oct 2009 10:47:06 GMT 服务器:Apache / 2.2.14(Win32) Last-Modified:星期六,2004年11月20日07:16:26 GMT ETag:“10000000565a5-2c-3e94b66c2e680” 接受范围:字节 内容长度:44 保持活跃:超时= 5,最大= 100 连接:保持活跃 内容类型:text / html <html> <body> <h1> It works!</ h1> </ body> </ html>
笔记:
- “”连接到主机丢失“(用于telnet)在
keep-alive
超时后出现 - 在出现“连接到主机丢失”消息(即,保持活动超时)之前,您可以通过相同的TCP连接发送另一个请求。
- 标题“
Connection: Keep-alive
”不区分大小写。该空间是可选的。 - 如果可选标题拼写错误或无效,它将被服务器忽略。
示例:访问受保护的资源
以下GET请求试图访问受保护的资源。服务器返回错误“403 Forbidden”。在本例中,目录“ htdocs\forbidden
”被配置为拒绝Apache HTTP服务器配置文件“ httpd.conf
” 中的所有访问,如下所示:
<目录“C:/ apache / htdocs / forbidden”> 订单否认,允许 否认所有人 </目录>
GET /forbidden/index.html HTTP / 1.0 (空行)
HTTP / 1.1 403禁止 日期:Sun,18 Oct 2009 11:58:41 GMT 服务器:Apache / 2.2.14(Win32) 内容长度:222 Keep-Alive:超时= 5,最大= 100 连接:保持活跃 内容类型:text / html; 字符集= ISO-8859-1 <!DOCTYPE HTML PUBLIC“ - // IETF // DTD HTML 2.0 // EN”> <HTML> <HEAD> <title> 403 Forbidden </ title> </ HEAD> <BODY> <H1>禁止</ H1> <p>您无权访问/forbidden/index.html 在这台服务器上。</ p> </ BODY> </ HTML>
HTTP / 1.1 GET请求
HTTP / 1.1服务器支持所谓的虚拟主机。也就是说,相同的物理服务器可以容纳多个虚拟主机,具有不同的主机名(例如www.nowhere123.com
和www.test909.com
)以及它们自己的专用文档根目录。因此,在HTTP / 1.1 GET请求中,必须包含名为“ Host
” 的请求标头,以选择其中一个虚拟主机。
示例:HTTP / 1.1请求
HTTP / 1.1默认保持持久(或保持活动)连接,以提高网络效率。您可以使用请求头“ Connection: Close
”来请求服务器在传递响应后关闭TCP连接。
GET /index.html HTTP / 1.1 主机:127.0.0.1 (空白行)
HTTP / 1.1 200 OK 日期:Sun,18 Oct 2009 12:10:12 GMT 服务器:Apache / 2.2.14(Win32) Last-Modified:星期六,2004年11月20日07:16:26 GMT ETag:“10000000565a5-2c-3e94b66c2e680” 接受范围:字节 内容长度:44 内容类型:text / html <html> <body> <h1> It works!</ h1> </ body> </ html>
示例:HTTP / 1.1缺少主机头
以下示例显示“ Host
”标头在HTTP / 1.1请求中是必需的。如果“ Host
”标题丢失,则服务器返回错误“400错误请求”。
GET /index.html HTTP / 1.1 (空行)
HTTP / 1.1 400错误请求 日期:Sun,18 Oct 2009 12:13:46 GMT 服务器:Apache / 2.2.14(Win32) 内容长度:226 连接:关闭 内容类型:text / html; 字符集= ISO-8859-1 <!DOCTYPE HTML PUBLIC“ - // IETF // DTD HTML 2.0 // EN”> <HTML> <HEAD> <title> 400错误请求</ title> </ HEAD> <BODY> <h1>错误请求</ h1> <p>您的浏览器发送了此服务器无法理解的请求。<br /> </ p> </ BODY> </ HTML>
条件GET请求
在所有前面的例子中,如果请求可以被满足(即无条件),服务器返回整个文档。您可以使用额外的请求头来发出“条件请求”。例如,要根据上次修改日期来请求文档(以决定是使用本地缓存副本)还是要求文档(或范围)的一部分而不是整个文档(对于下载大文件)。
条件请求标头包括:
If-Modified-Since
(检查响应状态码“304未修改”)。If-Unmodified-Since
If-Match
If-None-Match
If-Range
请求标题
本节介绍一些常用的请求标头。有关更多详细信息,请参阅HTTP规范。标题名称的语法是使用dash(-
)加入初始帽的单词,例如Content-Length
,If-Modified-Since
。
Host: domain-name
- HTTP / 1.1支持虚拟主机。多个DNS名称(例如,www.nowhere123.com和www.nowhere456.com)可以驻留在同一台物理服务器上,并拥有自己的文档根目录。 Host
在HTTP / 1.1中,头是强制性的以选择其中一个主机。
以下标题可用于客户端进行内容协商,以请求服务器提供文档的首选类型(根据媒体类型,例如JPEG与GIF,或使用的语言,如英语与法语),如果服务器为同一文件维护多个版本。
Accept: mime-type-1, mime-type-2, ...
- 客户端可以使用Accept
头来告诉服务器它可以处理的MIME类型,它更喜欢。如果服务器具有所请求文档的多个版本(例如,GIF和PNG中的图像,或者TXT和PDF中的文档),则它可以检查该标题以决定将哪个版本传递给客户端。(例如,PNG是更高级的更多GIF,但不是所有的浏览器都支持PNG。)这个过程称为内容类型协商。
Accept-Language: language-1, language-2, ...
- 客户端可以使用Accept-Language
头文件告诉服务器它可以处理什么语言或者更喜欢哪种语言。如果服务器有多个版本的请求文档(例如英文,中文,法文),它可以检查这个头来决定返回哪个版本。这个过程被称为语言谈判。
Accept-Charset: Charset-1, Charset-2, ...
- 对于字符集协商,客户端可以使用这个头来告诉服务器它可以处理哪些字符集或者更喜欢哪种字符集。字符集的例子是ISO-8859-1,ISO-8859-2,ISO-8859-5,BIG5,UCS2,UCS4,UTF8。
Accept-Encoding: encoding-method-1, encoding-method-2, ...
- 客户端可以使用这个头来告诉服务器它支持的编码类型。如果服务器具有所请求文档的编码(或压缩)版本,则它可以返回客户端支持的编码版本。服务器还可以在返回客户端之前选择对文档进行编码以减少传输时间。服务器必须设置响应头“ Content-Encoding
”以通知客户端返回的文档已被编码。常用的编码方法是“ x-gzip
(.gz
,.tgz
)”和“ x-compress
(.Z
)”。
Connection: Close|Keep-Alive
- 客户端可以使用这个头来告诉服务器在这个请求之后是否关闭连接,或者让另一个请求保持连接处于活动状态。HTTP / 1.1默认使用持久(保持活动)连接。HTTP / 1.0默认关闭连接。
Referer: referer-URL
- 客户端可以使用这个头来指示这个请求的引用者。如果您单击网页1上的链接访问网页2,则网页1是请求网页2的引用者。所有主流浏览器设置此标头,可用于跟踪请求的来源(用于网络广告或内容定制)。尽管如此,这个标头并不可靠,并且很容易被欺骗。请注意,推荐人被拼写为“Referer”(不幸的是,您也必须遵循)。
User-Agent: browser-type
- 确定用于提出请求的浏览器类型。服务器可以根据浏览器的类型使用此信息返回不同的文档。
Content-Length: number-of-bytes
- POST请求使用,通知服务器请求主体的长度。
Content-Type: mime-type
- 由POST请求使用,通知服务器请求主体的媒体类型。
Cache-Control: no-cache|...
- 客户端可以使用这个头来指定页面如何被代理服务器缓存。“ no-cache
”需要代理才能从原始服务器获取全新副本,即使本地缓存副本可用。(HTTP / 1.0服务器不能识别“ Cache-Control: no-cache
”,而是使用“ Pragma: no-cache
”,如果你不确定服务器的版本,请包括这两个请求头。)
Authorization
:由客户端用来提供其凭证(用户名/密码)以访问受保护的资源。(这个头文件将在后面的认证章节中描述。)
Cookie: cookie-name-1=cookie-value-1, cookie-name-2=cookie-value-2, ...
- 客户端使用此标头将cookie返回到服务器,该服务器之前由该服务器设置用于状态管理。(这个标题将在后面关于国家管理的章节中讨论。)
If-Modified-Since: date
- 告诉服务器仅在特定日期之后修改页面才发送页面。
GET请求目录
假设testdir
文档库目录“ htdocs
”中存在名为“ ”的目录。
如果客户端向“ /testdir/
” 发出GET请求(即在目录中)。
/testdir/index.html
如果目录包含一个“index.html
”文件,服务器将返回“ ” 。- 否则,如果在服务器配置中启用了目录列表,服务器将返回目录列表。
- 否则,服务器返回“找不到404页面”。
有趣的是,如果客户端向“ /testdir
” 发出GET请求(不指定目录路径"/
),则服务器返回“301永久移动”并带有新Location
的“ /testdir/
”,如下所示。
GET / testdir HTTP / 1.1 主机:127.0.0.1 (空行)
HTTP / 1.1 301永久移动 日期:2009年10月18日(星期日)13:19:15 GMT 服务器:Apache / 2.2.14(Win32) 地点:http://127.0.0.1:8000/testdir/ 内容长度:238 内容类型:text / html; 字符集= ISO-8859-1 <!DOCTYPE HTML PUBLIC“ - // IETF // DTD HTML 2.0 // EN”> <HTML> <HEAD> <title> 301永久移动</ title> </ HEAD> <BODY> <h1>永久移动</ h1> <p>该文件已移至<a href="http://127.0.0.1:8000/testdir/">此处</a>。</ p> </ BODY> </ HTML>
大多数浏览器会跟进另一个“ /testdir/
”的请求。例如,如果您从浏览器发出http://127.0.0.1:8000/testdir
没有尾随的“ /
”,您可能会注意到/
在给出响应之后在地址中添加了尾部“ ”。故事的士气是:你应该包含/
目录请求的“ ”以节省额外的GET请求。
通过代理服务器发出GET请求
要通过代理服务器发送GET请求,(a)建立到代理服务器的TCP连接; (b)使用绝对请求URI 到目标服务器。http://hostname:port/path/fileName
以下跟踪是使用telnet捕获的。与代理服务器建立连接,并发出GET请求。请求行中使用绝对请求URI。
GET http://www.amazon.com/index.html HTTP / 1.1 主持人:www.amazon.com 连接:关闭 (空行)
HTTP / 1.1 302找到 传输编码:分块 日期:2004年2月27日星期五09:27:35 GMT 内容类型:text / html; 字符集= ISO-8859-1 连接:关闭 服务器:Stronghold / 2.4.2 Apache / 1.3.6 C2NetEU / 2412(Unix) Set-Cookie:skin =; 域= .amazon.com; 路径= /; 到期=格林威治标准时间01日01月01日12:00:00 连接:关闭 位置:http://www.amazon.com:80/exec/obidos/subst/home/home.html 通过:1.1 xproxy(NetCache NetApp / 5.3.1R4D5) ED <!DOCTYPE HTML PUBLIC“ - // IETF // DTD HTML 2.0 // EN”> <HTML> <HEAD> <TITLE> 302找到</ TITLE> </ HEAD> <BODY> <H1>实测值</ H1> 文件已移动 <A HREF="http://www.amazon.com:80/exec/obidos/subst/home/home.html"> 这里</A>。<P> </ BODY> </ HTML> 0
请注意,响应以“块”形式返回。
“HEAD”请求方法
HEAD请求与GET请求类似。但是,服务器仅返回没有包含实际文档的响应主体的响应标头。HEAD请求是用于检查报头,如有用Last-Modified
,Content-Type
,Content-Length
,发送一个适当的GET请求来检索文档之前。
HEAD请求的语法如下所示:
HEAD request-URI HTTP版本 (其他可选请求标头) (空行) (可选请求体)
例
HEAD /index.html HTTP / 1.0 (空行)
HTTP / 1.1 200 OK 日期:Sun,18 Oct 2009 14:09:16 GMT 服务器:Apache / 2.2.14(Win32) Last-Modified:星期六,2004年11月20日07:16:26 GMT ETag:“10000000565a5-2c-3e94b66c2e680” 接受范围:字节 内容长度:44 连接:关闭 内容类型:text / html X-Pad:避免浏览器错误
请注意,响应只包含头部,而不包含实体文档。
“选项”请求方法
客户端可以使用OPTIONS请求方法来查询服务器支持哪些请求方法。OPTIONS请求消息的语法是:
选项request-URI | * HTTP版本 (其他可选标题) (空行)
“ *
”可以用来代替request-URI来表明请求不适用于任何特定的资源。
例
例如,通过代理服务器发送以下OPTIONS请求:
选项http://www.amazon.com/ HTTP / 1.1 主持人:www.amazon.com 连接:关闭 (空行)
HTTP / 1.1 200 OK 日期:2004年2月27日星期五09:42:46 GMT 内容长度:0 连接:关闭 服务器:Stronghold / 2.4.2 Apache / 1.3.6 C2NetEU / 2412(Unix) 允许:GET,HEAD,POST,OPTIONS,TRACE 连接:关闭 通过:1.1 xproxy(NetCache NetApp / 5.3.1R4D5) (空行)
所有允许GET请求的服务器都将允许HEAD请求。有时候HEAD没有列出。
“TRACE”请求方法
客户端可以发送TRACE请求来要求服务器返回诊断跟踪。
TRACE请求采用以下语法:
TRACE / HTTP版本 (空白行)
例
以下示例显示通过代理服务器发出的TRACE请求。
TRACE http://www.amazon.com/ HTTP / 1.1 主持人:www.amazon.com 连接:关闭 (空行)
HTTP / 1.1 200 OK 传输编码:分块 日期:2004年2月27日星期五09:44:21 GMT 内容类型:消息/ http 连接:关闭 服务器:Stronghold / 2.4.2 Apache / 1.3.6 C2NetEU / 2412(Unix) 连接:关闭 通过:1.1 xproxy(NetCache NetApp / 5.3.1R4D5) 9D TRACE / HTTP / 1.1 连接:保持活跃 主持人:www.amazon.com 通过:1.1 xproxy(NetCache NetApp / 5.3.1R4D5) X-Forwarded-For:155.69.185.59,155.69.5.234 0
(要将TRACE请求与跟踪路由进行比较)
提交HTML表单数据和查询字符串
在诸如电子商务和搜索引擎的许多互联网应用中,客户需要向服务器提交附加信息(例如,名称,地址,搜索关键字)。根据提交的数据,服务器采取适当的行动并产生定制的响应。
客户通常使用表单(使用HTML <form>
标签生成)。一旦他们填写所请求的数据并点击提交按钮,浏览器就会打包表单数据并使用GET请求或POST请求将它们提交给服务器。
以下是一个示例HTML表单,它由以下HTML脚本生成:
<HTML> <head> <title>示例HTML表单</ title> </ head> <BODY> <h2 align =“left”>一个示例HTML数据输入表单</ h2> <form method =“get”action =“/ bin / process”> 输入你的名字:<input type =“text”name =“username”> <br /> 输入您的密码:<input type =“password”name =“password”> <br /> 哪一年? <input type =“radio”name =“year”value =“2”/> Yr 1 <input type =“radio”name =“year”value =“2”/> Yr 2 <input type =“radio”name =“year”value =“3”/> Yr 3 <br /> 学科注册: <input type =“checkbox”name =“subject”value =“e101”/> E101 <input type =“checkbox”name =“subject”value =“e102”/> E102 <input type =“checkbox”name =“subject”value =“e103”/> E103 <br /> 选择日期: <select name =“day”> <option value =“mon”> Monday </ option> <option value =“wed”> Wednesday </ option> <option value =“fri”> Friday </ option> </ select> <br /> <textarea rows =“3”cols =“30”>在这里输入您的特殊要求</ textarea> <br /> <input type =“submit”value =“发送”/> <input type =“reset”value =“CLEAR”/> <input type =“hidden”name =“action”value =“registration”/> </ FORM> </ BODY> </ HTML>
表单包含字段。领域的类型包括:
- 文本框:由...制作
<input type="text">
。 - 密码框:由
<input type="password">
。制作。 - 单选按钮:由...制作
<input type="radio">
。 - 复选框:由
<input type="checkbox">
。制作。 - 选择:由
<select>
和生成<option>
。 - 文本区:由...制作
<textarea>
。 - 提交按钮:由...制作
<input type="submit">
。 - 重置按钮:由...生成
<input type="reset">
。 - 隐藏字段:由...制作
<input type="hidden">
。 - 按钮:由...制作
<input type="button">
。
每个字段都有一个名称并且可以具有指定的值。一旦客户端填入字段并点击提交按钮,浏览器就会收集每个字段的名称和值,并将它们打包成“ name=value
”对,然后使用“ &
”作为字段分隔符连接所有字段。这被称为查询字符串。它会将查询字符串作为请求的一部分发送到服务器。
name1 = value1 &name2 = value2 &name3 = value3 & ...
查询字符串中不允许有特殊字符。它们必须用“ %
”后面跟着十六进制ASCII码代替。例如,“ ~
”由“ %7E
”,“ #
”,“ %23
”等替换。由于空白很常见,可以用“ %20
”或“ +
” +
替换(“ ”字符必须替换为“ %2B
”)。这个替换过程称为URL编码,结果是一个URL编码的查询字符串。例如,假设表单中有3个字段,名称/值为“name = Peter Lee”,“address =#123 Happy Ave”和“language = C ++”,则URL编码查询字符串为:
name = Peter + Lee & address =%23123 + Happy + Ave & Language = C%2B%2B
查询字符串可以使用<form>
's属性“中指定的HTTP GET或POST请求方法发送到服务器method
。
<form method =“ get | post”action =“ url ”>
如果使用GET请求方法,那么URL编码的查询字符串将被附加在“ ”字符之后的request-URI后面?
,即,
GET 请求的URI ?查询字符串 HTTP版本 (其他可选请求标头) (空行) (可选请求体)
使用GET请求发送查询字符串有以下缺点:
- 您可以附加在request-URI后面的数据量是有限的。如果此数量超过服务器特定的阈值,服务器将返回一个错误“414请求URI太大”。
- URL编码的查询字符串将出现在浏览器的地址栏中。
POST方法克服了这些缺点。如果使用POST请求方法,则查询字符串将在请求消息的主体中发送,其中金额不受限制。请求标头Content-Type
并Content-Length
用于通知服务器查询字符串的类型和长度。查询字符串不会出现在浏览器的地址框中。POST方法将在后面讨论。
例
以下HTML表单用于在登录菜单中收集用户名和密码。
<HTML> <HEAD> <TITLE>登录</ TITLE> </ HEAD> <BODY> <H2> LOGIN </ H2> <form method =“get”action =“/ bin / login”> 用户名:<input type =“text”name =“user”size =“25”/> <br /> 密码:<input type =“password”name =“pw”size =“10”/> <br /> <br /> <input type =“hidden”name =“action”value =“login”/> <input type =“submit”value =“发送”/> </ FORM> </ BODY> </ HTML>
HTTP GET请求方法用于发送查询字符串。假设用户输入“Peter Lee”作为用户名,“123456”作为密码; 并点击提交按钮。以下GET请求是:
GET / bin / login?user = Peter + Lee&pw = 123456&action = login HTTP / 1.1 接受:image / gif,image / jpeg,* / * Referer:http://127.0.0.1:8000/login.html Accept-Language:en-us Accept-Encoding:gzip,deflate 用户代理:Mozilla / 4.0(兼容; MSIE 6.0; Windows NT 5.1) 主机:127.0.0.1:8000 连接:保持活跃
请注意,尽管您输入的密码并未显示在屏幕上,但它会在浏览器的地址栏中清晰显示。如果没有适当的加密,您绝不应该使用发送密码。
http://127.0.0.1:8000/bin/login?user=Peter+Lee&pw=123456&action=login
网址和URI
URL(统一资源定位器)
在RFC 2396中定义的URL(统一资源定位符)用于唯一标识网络上的资源。网址具有以下语法:
协议:// 主机名:端口 / 路径和文件名
网址中有4个部分:
- 协议:客户端和服务器使用的应用层协议,例如HTTP,FTP和Telnet。
- 主机名:服务器的DNS域名(例如www.nowhere123.com)或IP地址(例如192.128.1.2)。
- 端口:服务器正在侦听来自客户端的传入请求的TCP端口号。
- 路径和文件名:在服务器文档基础目录下的请求资源的名称和位置。
例如,在URL中http://www.nowhere123.com/docs/index.html
,通信协议是HTTP; 主机名是www.nowhere123.com。端口号未在URL中指定,并且采用默认号码,即HTTP [STD 2]的TCP端口80。要找到的资源的路径和文件名是“ /docs/index.html
”。
其他URL的例子有:
ftp://www.ftp.org/docs/test.txt 邮寄地址:user@test101.com 新闻:soc.culture.Singapore 远程登录://www.nowhere123.com/
编码的URL
网址不能包含特殊字符,例如空白或'~'
。特殊字符的编码形式为%xx
,其中xx是ASCII十六进制代码。例如,'~'
编码为%7e
; '+'
被编码为%2b
。空白可以编码为%20
或'+'
。编码后的URL称为编码的URL。
URI(统一资源标识符)
在RFC3986中定义的URI(统一资源标识符)比URL更普遍,它甚至可以在资源中定位片段。HTTP协议的URI语法是:
HTTP://主机:端口/路径请求参数#nameAnchor
- 请求参数以名称=值对的形式与URL分隔开
'?'
。名称=值对由a分隔'&'
。 - 所述
#nameAnchor
识别HTML文档内的片段,经由锚定标记定义。<a name="anchorName">...</a>
- 会话管理的URL重写,例如“
...;sessionID=xxxxxx
”。
“POST”请求方法
POST请求方法用于将附加数据“发布”到服务器(例如,提交HTML表单数据或上传文件)。从浏览器发出HTTP URL始终会触发GET请求。要触发POST请求,可以使用带有属性的HTML表单method="post"
或编写自己的网络程序。对于提交HTML表单数据,POST请求与GET请求相同,除了在请求正文中发送URL编码的查询字符串,而不是附加在request-URI后面。
POST请求采用以下语法:
POST request-URI HTTP-version Content-Type:MIME类型 Content-Length:字节数 (其他可选请求标头) (URL编码的查询字符串)
请求标头Content-Type
并且Content-Length
在POST请求中是必需的,以通知服务器媒体类型和请求主体的长度。
示例:使用POST请求方法提交表单数据
我们使用与上述相同的HTML脚本,但将请求方法更改为POST。
<HTML> <HEAD> <TITLE>登录</ TITLE> </ HEAD> <BODY> <H2> LOGIN </ H2> <form method =“post” action =“/ bin / login”> 用户名:<input type =“text”name =“user”size =“25”/> <br /> 密码:<input type =“password”name =“pw”size =“10”/> <br /> <br /> <input type =“hidden”name =“action”value =“login”/> <input type =“submit”value =“发送”/> </ FORM> </ BODY> </ HTML>
假设用户输入“Peter Lee”作为用户名,“123456”作为密码,点击提交按钮,浏览器将生成以下POST请求:
POST / bin / login HTTP / 1.1 主机:127.0.0.1:8000 接受:image / gif,image / jpeg,* / * Referer:http://127.0.0.1:8000/login.html Accept-Language:en-us 内容类型:application / x-www-form-urlencoded Accept-Encoding:gzip,deflate 用户代理:Mozilla / 4.0(兼容; MSIE 6.0; Windows NT 5.1) 内容长度:37 连接:保持活跃 缓存控制:无缓存 用户=彼得+李PW = 123456&行动=登录
请注意,Content-Type
标题通知服务器数据是URL编码的(使用特殊的MIME类型application/x-www-form-urlencoded
),并且Content-Length
标题告诉服务器从消息正文中读取多少字节。
POST与GET提交表单数据
如前一节所述,与发送查询字符串中的GET请求相比,POST请求具有以下优势:
- 可以发布的数据量是无限的,因为它们保存在请求主体中,通常在单独的数据流中发送到服务器。
- 查询字符串未显示在浏览器的地址栏中。
请注意,虽然密码未在浏览器的地址栏中显示,但会以明文形式发送到服务器,并受到网络嗅探的影响。因此,使用POST请求发送密码绝对不安全。
使用multipart/form-data
POST请求上传文件
“RFC 1867:基于表单的HTML文件上传”指定了如何使用来自HTML表单的POST请求将文件上传到服务器。一个新的属性type="file"
被添加到<input>
HTML 的标签<form>
以支持文件上传。文件上传POST数据不是URL编码的(在标准中application/x-www-form-urlencoded
),但使用新的MIME类型multipart/form-data
。
例
以下HTML表单可用于文件上传:
<HTML> <head> <title>文件上传</ title> </ head> <BODY> <h2>上传档案</ h2> <form method =“post”enctype =“multipart / form-data” action =“servlet / UploadServlet”> 你是谁:<input type =“text”name =“username”/> <br /> 选择要上传的文件: <input type =“file”name =“fileID”/> <br /> <input type =“submit”value =“发送”/> </ FORM> </ BODY> </ HTML>
当浏览器遇到<input>
带有属性的标签时type="file"
,它会显示一个文本框和一个“浏览...”按钮,以允许用户选择要上传的文件。
当用户点击提交按钮时,浏览器发送表单数据和所选文件的内容。旧的编码类型“ application/x-www-form-urlencoded
”对于发送二进制数据和非ASCII字符效率不高。multipart/form-data
代替使用新的媒体类型“ ”。
每个部分标识原始HTML表单中的输入名称,以及媒体是已知的内容类型,application/octet-stream
否则标识内容类型。
原始的本地文件名可以作为filename
参数提供,或者在“ Content-Disposition: form-data
”标题中提供。
文件上传的POST消息示例如下所示:
POST / bin /上传HTTP / 1.1 主持人:test101 接受:image / gif,image / jpeg,* / * Accept-Language:en-us 内容类型:multipart / form-data; 边界= --------------------------- 7d41b838504d8 Accept-Encoding:gzip,deflate 用户代理:Mozilla / 4.0(兼容; MSIE 6.0; Windows NT 5.1) 内容长度:342 连接:保持活跃 缓存控制:无缓存 ----------------------------- 7d41b838504d8 Content-Disposition:form-data; NAME = “用户名” 彼得李 ----------------------------- 7d41b838504d8 Content-Disposition:form-data; NAME = “FILEID”; filename =“C:\ temp.html”Content-Type:text / plain <h1>主服务器上的主页</ h1> ----------------------------- 7d41b838504d8--
Servlet 3.0为处理文件上传提供了内置的支持。阅读“ 在Servlet 3.0中上传文件 ”。
“连接”请求方法
HTTP CONNECT请求用于请求代理与另一个主机建立连接,并简单地中继内容,而不是试图解析或缓存消息。这通常用于通过代理进行连接。
( 正在施工🚧)
其他请求方法
PUT:请求服务器存储数据。
删除:请求服务器删除数据。
出于安全考虑,大多数生产服务器不支持PUT和DELETE。
可以定义扩展方法(也包括错误代码和头文件)以扩展HTTP协议的功能。
( 正在施工🚧)
内容谈判
如前所述,HTTP支持客户端和服务器之间的内容协商。客户端可以使用额外的请求标题(如Accept
,Accept-Language
,Accept-Charset
,Accept-Encoding
),以判断哪些内容是更喜欢什么样的服务器,它可以处理或。如果服务器拥有不同格式的同一文档的多个版本,则它将返回客户端偏好的格式。这个过程被称为内容协商。
内容类型谈判
服务器使用MIME配置文件(称为“ conf\mime.types
”)将文件扩展名映射到媒体类型,以便通过查看其文件扩展名来确定文件的媒体类型。例如,文件扩展名“ .htm
”,“ .html
”与MIME媒体类型“ text/html
” 相关联,“ ”,“ ”的文件扩展名与“ .jpg
” .jpeg
相关联image/jpeg
。当文件返回给客户端时,服务器必须建立一个Content-Type
响应头来通知客户端数据的媒体类型。
对于内容类型协商,假设客户端请求文件调用“ logo
”而不指定其类型,并发送一个标题“ Accept: image/gif, image/jpeg,...
”。如果服务器有两种格式的“ logo
”:“ logo.gif
”和“ logo.jpg
”,并且MIME配置文件具有以下条目:
图片/ gif gif 图像/ jpeg jpeg jpg jpe
服务器将logo.gif
根据客户Accept
机头和MIME类型/文件映射将“ ” 返回给客户机。服务器将Content-type: image/gif
在其响应中包含一个“ ”标题。
显示消息跟踪:
GET / logo HTTP / 1.1 接受:image / gif,image / x-xbitmap,image / jpeg,image / pjpeg, application / x-shockwave-flash,application / vnd.ms-excel, application / vnd.ms-powerpoint,application / msword,* / * Accept-Language:en-us Accept-Encoding:gzip,deflate 用户代理:Mozilla / 4.0(兼容; MSIE 6.0; Windows NT 5.1) 主持人:test101:8080 连接:保持活跃 (空行)
HTTP / 1.1 200 OK 日期:2004年2月29日星期日01:42:22 GMT 服务器:Apache / 1.3.29(Win32) 内容 - 位置:logo.gif 变化:谈判,接受 TCN:选择 Last-Modified:Wed,21 Feb 1996 19:45:52 GMT ETag:“0-916-312b7670; 404142de” 接受范围:字节 内容长度:2326 Keep-Alive:超时= 15,最大= 100 连接:保持活跃 Content-Type:image / gif (空行) (省略身体)
但是,如果服务器有3个“ logo.*
”文件,则使用“ logo.gif
”,“ logo.html
”,“ logo.jpg
”和“ Accept: */*
”:
GET / logo HTTP / 1.1 接受:* / * Accept-Language:en-us Accept-Encoding:gzip,deflate 用户代理:Mozilla / 4.0(兼容; MSIE 6.0; Windows NT 5.1) 主持人:test101:8080 连接:保持活跃 (空行)
HTTP / 1.1 200 OK 日期:2004年2月29日星期日01:48:16 GMT 服务器:Apache / 1.3.29(Win32) 内容 - 位置:logo.html 变化:谈判,接受 TCN:选择 Last-Modified:Fri,2004年2月20日04:31:17 GMT ETag:“0-10-40358d95; 404144c1” 接受范围:字节 内容长度:16 Keep-Alive:超时= 15,最大= 100 连接:保持活跃 内容类型:text / html (空行) (省略身体)
接受:* / *
以下Apache的配置指令与内容类型协商相关:
- 该
TypeConfig
指令可用于指定MIME映射文件的位置:TypeConfig conf / mime.types
- 该
AddType
指令可用于在配置文件中包含附加的MIME类型映射:AddType mime-type extension1 [ extension2 ]
- 该
DefaultType
指令给出未知文件扩展名的MIME类型(在Content-Type
响应头中)DefaultType文本/纯文本
语言谈判和“选项多视图”
“ Options MultiView
”指令是实现语言协商的更简单的方法。例如:
AddLanguage en .en <目录“C:/ _ javabin / Apache1.3.29 / htdocs”> 选项索引MultiViews </目录>
假设客户端请求“ index.html
”并发送“ Accept-Language: en-us
”。如果服务器有“ test.html
”,“ test.html.en
”和“ test.html.cn
”,根据客户的偏好,test.html.en
将返回“ ”。(“ en
”包括“ en-us
”)。
消息跟踪如下所示:
GET /index.html HTTP / 1.1 接受:* / * Accept-Language:en-us Accept-Encoding:gzip,deflate 用户代理:Mozilla / 4.0(兼容; MSIE 6.0; Windows NT 5.1) 主持人:test101:8080 连接:保持活跃 (空行)
HTTP / 1.1 200 OK 日期:2004年2月29日星期日02:08:29 GMT 服务器:Apache / 1.3.29(Win32) 内容 - 位置:index.html.en 变化:谈判 TCN:选择 Last-Modified:Sun,29 Feb 2004 02:07:45 GMT ETag:“0-13-40414971; 40414964” 接受范围:字节 内容长度:19 Keep-Alive:超时= 15,最大= 100 连接:保持活跃 内容类型:text / html 内容语言:en (空行) (省略身体)
该AddLanguage
指令需要将语言代码与文件扩展名关联,类似于MIME类型/文件映射。
请注意,“ Options All
”指令不包括“ MultiViews
”选项。也就是说,你必须明确地打开MultiViews。
该指令LanguagePriority
可用于指定在内容协商过程中发生平局的情况下的语言偏好,或者客户端不表示偏好。例如:
<IfModule mod_negotiation.c> LanguagePriority en da nl et fr de el it ja kr no pl pt pt-br </ IfModule>配置
字符集谈判
客户端可以使用请求头Accept-Charset
与服务器协商它所喜欢的字符集。
Accept-Charset:charset-1,charset-2,...
常见的字符集包括:ISO-8859-1(Latin-I),ISO-8859-2,ISO-8859-5,BIG5(繁体中文),GB2312(简体中文),UCS2(2字节Unicode), UCS4(4字节Unicode),UTF8(编码Unicode)等。
同样,该AddCharset
指令用于将文件扩展名与字符集相关联。例如:
AddCharset ISO-8859-8 .iso8859-8 AddCharset ISO-2022-JP .jis AddCharset Big5 .Big5 .big5 AddCharset WINDOWS-1251 .cp-1251 AddCharset CP866 .cp866 AddCharset ISO-8859-5 .iso-ru AddCharset KOI8-R .koi8-r AddCharset UCS-2 .ucs2 AddCharset UCS-4 .ucs4 AddCharset UTF-8 .utf8
编码谈判
客户端可以使用Accept-Encoding
头来告诉服务器它支持的编码类型。常见的编码方案是:“ x-gzip (.gz, .tgz)
”和“ x-compress (.Z)
”。
Accept-Encoding:encoding-method-1,encoding-method-2,...
同样,该AddEncoding
指令用于将文件扩展名与编码方案相关联。例如:
AddEncoding x-compress .Z AddEncoding x-gzip .gz .tgz
持久(或保持活动)连接
在HTTP / 1.0中,服务器在默认传递响应(Connection: Close
)后关闭TCP连接。也就是说,每个TCP连接只服务一个请求。由于许多HTML页面包含超链接(通过<a href="url">
标签)到其他资源(例如图像,脚本 - 本地或远程服务器),因此效率不高。如果您下载包含5个内嵌图像的页面,浏览器必须建立TCP连接6次到同一台服务器。
客户端可以与服务器进行协商,并要求服务器在传递响应后不要关闭连接,以便可以通过相同的连接发送另一个请求。这被称为持久连接(或保持连接)。持久连接大大提高了网络的效率。对于HTTP / 1.0,默认连接是非持久性的。要请求持续连接,客户端必须Connection: Keep-alive
在请求消息中包含一个请求头“ ”来与服务器进行协商。
对于HTTP / 1.1,默认连接是持久的。客户端不必发送“ Connection: Keep-alive
”标题。相反,客户端可能希望发送头部“ Connection: Close
”来要求服务器在传递响应后关闭连接。
持久连接对于具有许多小型嵌入式图像和其他相关数据的网页非常有用,因为所有这些都可以使用相同的连接下载。持久连接的好处是:
- 在客户端,代理服务器,网关和原始服务器中打开和关闭TCP连接的CPU时间和资源节省。
- 请求可以“流水线”。也就是说,客户端可以在不等待每个响应的情况下发出多个请求,从而更高效地使用网络。
- 无需时间执行TCP的连接打开握手即可更快响应。
在Apache HTTP服务器中,几个配置指令与持久连接有关:
该KeepAlive
指令决定是否支持持久连接。这需要打开或关闭的值。
KeepAlive开|关
该MaxKeepAliveRequests
指令设置可以通过持久连接发送的最大请求数。您可以将其设置为0以允许无限数量的请求。为了获得更好的性能和网络效率,建议设置较高的数字。
MaxKeepAliveRequests 200
该KeepAliveTimeOut
指令设置持续连接等待下一个请求的超时时间。
KeepAliveTimeout 10
缓存控制
客户端可以发送一个请求头“ Cache-control: no-cache
”来告诉代理从原始服务器获取全新副本,即使认为存在本地缓存副本。不幸的是,HTTP / 1.0服务器不理解这个头,但使用了一个较老的请求头“ Pragma: no-cache
”。您可以在请求中包含这两个标头。
Pragma:无缓存 缓存控制:无缓存
参考与资源
- W3C HTTP规范在http://www.w3.org/standards/techs/http。
- RFC 2616“超文本传输协议HTTP / 1.1”,1999 @ http://www.ietf.org/rfc/rfc2616.txt。
- RFC 1945“超文本传输协议HTTP / 1.0”,1996 @ http://www.ietf.org/rfc/rfc1945.txt。
- 性病2:“分配号码”,1994年。
- STD 5:“互联网协议(IP)”,1981。
- STD 6:“用户数据报协议(UDP)”,1980。
- STD 7:“传输控制协议(TCP)”,1983。
- RFC 2396:“统一资源标识符(URI):通用语法”,1998。
- RFC 2045:“多用途Internet邮件扩展(MIME)第1部分:Internet消息体的格式”,1996。
- RFC 1867:1995年“基于HTML的基于表单的文件上传”(由RFC2854废弃)。
- RFC 2854:“文本/ html媒体类型”,2000。
- 用于文件上传@ www.servlets.com的 Mutlipart Servlet
最新版本测