在http 1.0版中,请求头中是不带host行的,到了http 1.1后,加入了host行
http request header 中的host行:
GET / HTTP/1.1
Host: www.google.com.cn
一台网络服务器上面可以放成千上万个网站(虚拟主机),当对这些网站的请求到来时,服务器能够根据Host这一行中的值来确定本次请求的是哪个具体的网站
http 1.1中不能缺失host行,如果缺失,服务器返回400 bad reques
通过telnet程序连接上tomcat服务器上的8080端口,此端口其实就tomcat用来监听http请求的端口
同时按下Ctrl+] 回车,打开telnet回显功能
此时就可以看到我们输入的内容了
测试向Tomcat服务器发送请求
GET请求
POST请求
缓存相关的头
禁止浏览器缓存
Pragma: no-cache HTTP1.0
Cache-Control: no-cache
Expires: 0
服务器响应头:Last-Modified / Etag
客户端请求头:If-Modified-Since / If-None-Match
客户端(浏览器)第一次向服务器请求某个web组件,服务器返回的响应中会包含Etag,Last-Modified头,下次客户端再向服务器请求同一web组件,会将上一次服务器返回的Etag值作为If-None-Match头,将Last-Modified的值作为If-Modified-Since头作为请求头发给服务器,服务器会根据这些头信息判断请求的web组件是否为最新的,若没有更新,则简单返回304状态码,让客户端拿本地缓存。如果需要更新,则返回最新的web组件内容,同时包含新的Etag / Last-Modified头。这种机制可以避免服务器重复发送内容给客户端,但是还是会产生一个HTTP请求/响应。
Etag:W/"324-1379566963526"
ETag是响应头,If-None-Match是请求头。Last-Modified / If-Modified-Since的主要缺点就是它只能精确到秒的级别,一旦在一秒的时间里出现了多次修改,那么Last-Modified / If-Modified-Since是无法体现的。相比较,ETag / If-None-Match没有使用时间作为判断标准,而是使用一个特征串。Etag把Web组件的特征串告诉客户端,客户端在下次请求此Web组件的时候,会把上次服务端响应的特征串作为If-None-Match的值发送给服务端,服务端可以通过这个值来判断是否需要从重新发送,如果不需要,就简单的发送一个304状态码,客户端将从缓存里直接读取所需的Web组件。
服务器发出的响应,还可以通过Expires和Cache-Control头告诉客户端缓存web组件
Expires: Thu, 19 Sep 2013 05:02:43 GMT
如果服务器时间和客户端时间不一致,会导致这个头失效。
Cache-Control:max-age=5 单位是秒,时间是相对客户端的,不会出现Expires头的问题。
Expires头在HTTP1.0和HTTP1.1下都有效,而Cache-Control只在HTTP1.1下有效,大多数情况下同时发送这两个头会是更好的选择,客户端会优先使用Cache-Control头。
响应中同时包含Expires/Cache-Control头和Last-Modified/Etag头是一种比较好的处理方式,如果用户仅仅只是在浏览器地址栏上回车重新访问一次web组件,如果此时Expires/Cache-Control指定的过期时间还没到,则不会再向服务器端发送请求。如果用户通过F5重新请求某个web组件,此时Last-Modified/Etag就起作用了,若请求的web组件不需要更新,服务器端仅仅只返回304状态码。
Etag的弊端
对于只有一个Server的网站,Etag使用没什么问题,但是现在稍微上点规模的网站都需要Scale Out,也就是说需要前端一个Load Balancer,后面接多台Server来处理请求,俗称Cluster,既然是Cluster,那么每个请求到底返回什么结果应该和分配到哪个 Server无关,不过这个ETag可能就坏事了。假如用户的第一次请求分配给Server A,返回“ETag: "abcdefg1234:0001"”,但是第二次请求分配给了Server B,Server B上这个资源和Server A上的一模一样,但是计算出这个资源的ETag是"abcdefg1234:0002",这下麻烦了,虽然内容一样,但是ETag不匹配,还是浪费了带宽把资源发送了一遍,冤枉啊!而事实上,不同Server上的ETag很有可能不同,对于Apache,ETag的计算考虑了inode,对于 IIS,ETag考虑了metabase的修改版本,要保证不同server上的这些信息一致,有点小难。不过不是有Last-Modified/If- Not-Modified吗?Server端看到If-Modified-Since,对照一下时间对得上,不管If-None-Match,可以直接发回304(Not Modified)呀,很不幸,RFC2616对这种情况做了规定,如果既有If-None-Match又有If-Modified-Since,除非两者不冲突,不然不会返回304。
参考:
http://tech110.blog.51cto.com/438717/549764
/**
* Ctrl+F5 强制刷新 不管有没有缓存,都向服务器发送请求,且请求头中不包含If-Modified-Since等头字段
* 会包含Cache-Control:no-cache和Pragma:no-cache
*
* F5 会向服务器发送请求,同时会将If-Modified-Since请求头带上, Expires和Cache-Control无效
*
* 直接在浏览器地址栏回车,如果上一次响应中包含了Expires或Cache-Control头信息, 且时间还没有过期, 则不会再向服务器发出请求
*/
long time = request.getDateHeader("If-Modified-Since");
System.out.println(time);
if ((time + 60 * 1000) > new Date().getTime()) {
//如果距离上一次请求的时间不到60秒,返回304,让客户端直接拿缓存数据
response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
return;
}
response.setContentType("text/html;charset=UTF-8");
response.setDateHeader("Last-Modified", new Date().getTime());
response.setDateHeader("Expires", new Date().getTime() + 60 * 1000); //毫秒
response.setHeader("Cache-Control", "max-age=60");//秒
response.getWriter().write("Hello, World!!!");
response.getWriter().write("<br/>");
response.getWriter().write("你好,世界!!!");
Transfer-Encoding: chunked
HTTP1.1下,如果服务器端返回的内容不能一次传递完,需要经过多次传送,则会在响应头中加入Transfer-Encoding头,告知客户端。如果数据是一次传完,响应头中会包含Content-Length头,告诉客户端接收内容的长度。
GenerateImageServlet.java
//以流的方式将一张图片写到客户端,每次写1000字节
byte[] buf = new byte[1000];
int len = 0;
while (-1 != (len = in.read(buf))) {
response.getOutputStream().write(buf, 0, len);
response.getOutputStream().flush();
}
MainTest.java
//连上tomcat,发送一个HTTP请求,打印接收到的响应内容
Socket client = new Socket(InetAddress.getByName("localhost"), 8080);
InputStream in = client.getInputStream();
OutputStream out = client.getOutputStream();
//请求行
out.write("GET /tomcat_cache/GenerateImageServlet HTTP/1.1\r\n"
.getBytes());
//请求头
out.write("Host: localhost\r\n".getBytes());
//一个空行加实体内容,由于此处是GET请求,不包含实体内容。
out.write("\r\n\r\n".getBytes());
out.flush();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line = null;
while (null != (line = reader.readLine())) {
System.out.println(line);
}
out.close();
reader.close();
client.close();
####################运行结果#####################
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=E9A08F1E2B1F491DD13F66ABBA6ABA62; Path=/tomcat_cache
Transfer-Encoding: chunked
Date: Thu, 19 Sep 2013 07:28:55 GMT
3e8(十六进制,表示传递的数据长度为1000字节)
#$%ERT#$^@$@#$@^%$&%$(二进制串)
3e8
#$%ERT#$^@$@#$@^%$&%$(二进制串)
......
0(表示没有可传递的数据了)
- 大小: 6.9 KB
- 大小: 94.7 KB
- 大小: 95.1 KB
分享到:
相关推荐
一般通用web程序是如果...Hostheader(比如在php里是_SERVER["HTTP_HOST"]),而这个header很多情况下是靠不住的。而很多应用是直接把这个值不做html编码便输出到了页面中,比如:还有的地方还包含有secretkey和token,
在开发Vue.js应用程序时,你可能会遇到一个名为`Invalid Host header`的错误,尤其是在使用@Vue/Cli 3工具链时。这个错误通常出现在你尝试在非标准的或自定义的HTTP主机头环境下运行Vue CLI的开发服务器时。在本文中...
### JSP获取HTTP Header信息(Request)详解 在Web开发中,了解如何获取HTTP请求头信息是非常重要的,因为这些信息能够帮助我们更好地理解客户端环境、优化响应策略以及进行安全性检查等。下面将详细介绍JSP中如何...
HTTP协议Header详解是html帮助格式的,方便查询, 通过HTTP协议RFC2616整理的, 目录: 头域定义 2 1 Accept 2 2 Accept-Charset 4 3 Accept-Encoding 5 4 Accept-Language 6 5 Accept-Range 7 6 Age 7 7 Allow 8 8 ...
"HTTP_HOST 和 SERVER_NAME 的区别详解" HTTP_HOST 和 SERVER_NAME 是两种常见的Server Variables,在Web开发中经常使用,但它们之间的区别一直以来都是开发者们讨论的热门话题。今天,我们将详细探讨这两者的差异...
HTTP签名标头(http-signature-header) 一个用于创建和验证HTTP签名标头JavaScript库 目录 背景 安装 要在本地安装(用于开发): git clone https://github.com/digitalbazaar/http-signature-header.git cd ...
标题中的“host主机头漏洞”是指在Web服务器配置中,如果允许任意的主机头(Host Header)请求,可能会导致安全问题。主机头是HTTP请求的一部分,用于标识客户端想要访问的服务器域名。当服务器配置不当,它可能响应...
HTTP Headers 是 HTTP 协议的重要组成部分,用于在客户端(如浏览器)和服务器之间传递信息。HTTP 协议是万维网的基础,几乎所有网页内容的传输都依赖于它。HTTP Headers 负责携带有关请求、响应以及客户端和服务器...
### TCP/IP-HTTP-Header-消息报头 在TCP/IP协议族中,HTTP(超文本传输协议)是一种应用层协议,用于从Web服务器传输超文本到本地浏览器的传输协议。HTTP报文由请求行、状态行、首部字段(Header)、空行以及可选的...
$ npm install header-hostname 用法 var http = require ( 'http' ) ; var headerHostname = require ( "header-hostname" ) ; http . createServer ( function ( req , res ) { // hostname = "example.com", ...
### HTTP协议的Header头信息详解 #### 一、引言 在进行Web开发或网络开发时,理解HTTP协议中的Header头信息是至关重要的。HTTP(Hypertext Transfer Protocol)是一种应用层协议,用于从Web服务器传输超文本到本地...
HTTP Header 是超文本传输协议(HTTP)中极为关键的一部分,用于在客户端(如浏览器)和服务器之间传递附加信息,这些信息包括请求的细节、响应的状态以及关于数据内容的元信息。HTTP Header 可以帮助优化通信效率,...
Engine会根据请求的主机头(Host header)来决定将请求转发给哪个Host处理。 接下来是“Host”(主机)。Host是Engine下的子容器,代表了一个虚拟主机。在实际应用中,一台服务器可能托管着多个网站,每个网站对应...
根据提供的标题、描述以及部分上下文内容,我们可以推断出本次讨论主要集中在HTTP头部测试以及一个与Oracle数据库相关的场景上。下面将详细解释这些知识点。 ### HTTP头部测试 #### 1. **HTTP头部概述** - **定义...
HTTP头(HTTP Header)是HTTP协议中的一个重要组成部分,它包含了请求头、响应头、通用头等多种类型,用于传递额外的信息,如客户端的偏好、身份验证、缓存控制等。以下是对HTTP头的一些关键知识点的详细解释: 1. ...
proxy_set_header Host $host; # 保留代理之前的真实客户端 ip proxy_set_header X-Real-IP $remote_addr; # 这个 Header 和 X-Real-IP 类似,但它在多级代理时会包含真实客户端及中间每个代理服务器的IP proxy...
这时,我们就需要借助`UnityWebRequest`类,它是Unity3D 5.5版本之后引入的更强大的网络请求工具,支持更丰富的功能,包括自定义Header。 使用`UnityWebRequest`设置Headers的例子如下: ```csharp using ...
httpheader 这是一个Go包,用于正确解析和生成标准HTTP标头。 它知道复杂的标头,例如 , 和 。 与许多其他实现不同,它处理语法的所有棘手位,例如带逗号,标题行和参数。 它为您提供了方便的结构,并且可以将它们...
前言 开发网关项目时,在请求时往请求头header中放入了签名sign_key信息,在接收请求时再从header中拿出,在本地调试时... proxy_set_header Host $http_host; proxy_set_header X-Nginx-Proxy true; add_header Pro
HTTP 响应码和 Header 信息介绍文档 HTTP 响应码是指在 HTTP 协议中,服务器返回给客户端的状态码,用于表明请求的结果。响应码由三位十进制数字组成,分为五种类型,即信息、成功、重定向、客户端错误和服务器错误...