一、响应头格式
HTTP/1.1 状态
二、响应的格式
响应头 http/1.1 200 ok
content-type:text/html;charset = utf-8;
#显示中文
Content-Length: 10749显示内容的长度
空行
响应体
三、请求头的作用
告诉服务器我们请求地址
四、常见请求头
Accept:告诉服务器,客户端支持的数据类型。
Accept-Charset:告诉服务器,客户端采用的编码。
Accept-Encoding:告诉服务器,客户机支持的数据压缩格式。
Accept-Language:告诉服务器,客户机的语言环境。
Host:客户机通过这个头告诉服务器,想访问的主机名。
If-Modified-Since:客户机通过这个头告诉服务器,资源的缓存时间。
Referer:客户机通过这个头告诉服务器,它是从哪个资源来访问服务器的。(一般用于防盗链)
User-Agent:客户机通过这个头告诉服务器,客户机的软件环境。
Cookie:客户机通过这个头告诉服务器,可以向服务器带数据。
Connection:客户机通过这个头告诉服务器,请求完后是关闭还是保持链接。
Date:客户机通过这个头告诉服务器,客户机当前请求时间
五、响应的作用
控制浏览器的显示
六、状态
200 ok 成功了
302 found 跳转
400 Bad Request 由于客户端请求有语法错误,不憋服务器所理解
401 Unauthonzed 请求未经授权。这个状态代码必须和WWW-Authenticate报头域一起使用
403 Not Found 请求的资源不存在,例如,输入了错误的URL
404 not found 请求资源不存在,例如,输入了错误的URL
500 Internal Server Error 服务器发生了不可预期的错误,导致无法完成客户端的请求
503 Service Unavailable 服务器当前不能够处理客户端的请求,在一段时间之后,服务器可能会恢复正常
原:https://blog.csdn.net/uzizi/article/details/80085361
状态代码:状态代码由3位数字组成,表示请求是否被理解或被满足。
状态描述:状态描述给出了关于状态代码的简短的文字描述。
状态代码的第一个数字定义了响应的类别,后面两位没有具体的分类。
第一个数字有五种可能的取值:
- 1xx: 指示信息—表示请求已接收,继续处理。
- 2xx: 成功—表示请求已经被成功接收、理解、接受。
- 3xx: 重定向—要完成请求必须进行更进一步的操作。
- 4xx: 客户端错误—请求有语法错误或请求无法实现。
- 5xx: 服务器端错误—服务器未能实现合法的请求。
状态代码状态描述 说明
200 OK 客户端请求成功
400 Bad Request 由于客户端请求有语法错误,不能被服务器所理解。
401 Unauthonzed 请求未经授权。这个状态代码必须和WWW-Authenticate报头域一起使用
403 Forbidden 服务器收到请求,但是拒绝提供服务。服务器通常会在响应正文中给出不提供服务的原因
404 Not Found 请求的资源不存在,例如,输入了错误的URL。
500 Internal Server Error 服务器发生不可预期的错误,导致无法完成客户端的请求。
503 Service Unavailable 服务器当前不能够处理客户端的请求,在一段时间之后,服务器可能会恢复正常。
响应头:
响应头可能包括:
Location:Location响应报头域用于重定向接受者到一个新的位置。例如:客户端所请求的页面已不存在原先的位置,为了让客户端重定向到这个页面新的位置,服务器端可以发回Location响应报头后使用重定向语句,让客户端去访问新的域名所对应的服务器上的资源。当我们在JSP中使用重定向语句的时候,服务器端向客户端发回的响应报头中,就会有Location响应报头域。
Server:Server响应报头域包含了服务器用来处理请求的软件信息。它和User-Agent请求报头域是相对应的,前者发送服务器端软件的信息,后者发送客户端软件(浏览器)和操作系统的信息。下面是Server响应报头域的一个例子:Server: Apache-Coyote/1.1
WWW-Authenticate:WWW-Authenticate响应报头域必须被包含在401(未授权的)响应消息中,这个报头域和前面讲到的Authorization请求报头域是相关的,当客户端收到401响应消息,就要决定是否请求服务器对其进行验证。如果要求服务器对其进行验证,就可以发送一个包含了 Authorization报头域的请求,下面是WWW-Authenticate响应报头域的一个例子:WWW-Authenticate: Basic realm="Basic Auth Test!"
从这个响应报头域,可以知道服务器端对我们所请求的资源采用的是基本验证机制。
Content-Encoding:Content-Encoding实体报头域被使用作媒体类型的修饰符,它的值指示了已经被应用到实体正文的附加内容编码,因而要获得Content- Type报头域中所引用的媒体类型,必须采用相应的解码机制。Content-Encoding主要用语记录文档的压缩方法,下面是它的一个例子: Content-Encoding: gzip。如果一个实体正文采用了编码方式存储,在使用之前就必须进行解码。
Content-Language:Content-Language实体报头域描述了资源所用的自然语言。Content-Language允许用户遵照自身的首选语言来识别和区分实体。如果这个实体内容仅仅打算提供给丹麦的阅读者,那么可以按照如下的方式设置这个实体报头域:Content-Language: da。
如果没有指定Content-Language报头域,那么实体内容将提供给所以语言的阅读者。
Content-Length: Content-Length实体报头域用于指明正文的长度,以字节方式存储的十进制数字来表示,也就是一个数字字符占一个字节,用其对应的ASCII码存储传输。
要注意的是:这个长度仅仅是表示实体正文的长度,没有包括实体报头的长度。
Content-Type
Content-Type实体报头域用语指明发送给接收者的实体正文的媒体类型。例如:
Content-Type: text/html;charset=ISO-8859-1
Content-Type: text/html;charset=GB2312
Last-Modified
Last-Modified实体报头域用于指示资源最后的修改日期及时间。
Expires
Expires实体报头域给出响应过期的日期和时间。通常,代理服务器或浏览器会缓存一些页面。当用户再次访问这些页面时,直接从缓存中加载并显示给用户,这样缩短了响应的时间,减少服务器的负载。为了让代理服务器或浏览器在一段时间后更新页面,我们可以使用Expires实体报头域指定页面过期的时间。当用户又一次访问页面时,如果Expires报头域给出的日期和时间比Date普通报头域给出的日期和时间要早(或相同),那么代理服务器或浏览器就不会再使用缓存的页面而是从服务器上请求更新的页面。不过要注意,即使页面过期了,也并不意味着服务器上的原始资源在此时间之前或之后发生了改变。
Expires实体报头域使用的日期和时间必须是RFC 1123中的日期格式,例如:
Expires: Thu, 15 Sep 2005 16:00:00 GMT
HTTP1.1的客户端和缓存必须将其他非法的日期格式(也包括0)看作已过期。例如,为了让浏览器不要缓存页面,我们也可以利用Expires实体报头域,设置它的值为0,如下(JSP):response.setDateHeader("Expires",0);
下面是一个HTTP响应的例子:
HTTP/1.1 200 OK
Server:Apache Tomcat/5.0.12
Date:Mon,6Oct2003 13:23:42 GMT
Content-Length:112
请求头
Accept: 例: Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8 表示客户端支持的数据格式,或者说客户端“希望”接受到的内容类型。 这里只是希望,但是服务器具体返回什么样的内容类型,还是由服务器自己决定,但是无论服务器返回什么样的内容类型,客户端都会接收响应报文,不可能说因为内容类型不同,接收不到服务器响应报文,这不符合http协议规范。
我们通过浏览器发起get或post请求,该字段都是浏览器自动添加的,同样在服务器端也不会解析该字段的值; 通过ajax请求或其他手段,我们可以设置该字段的值,但是通常也不进行设置。
该字段的应用场景可以是这样的,有两个终端,比如一个是纯文本阅读器,如Kinder(不能显示图片),另一个是移动终端(可以播放图片和视频),均向服务器请求有关“斑马”的信息,那么这时候服务器端就需要判断什么样的终端应该返回什么样的信息,那么它就可以根据Accept的信息来进行判断,如果解析到的Accept的值为“text/plain”,那么就表示客户端只支持文本类型;如果向上面例子中的那样,则表示客户端文本图片视频都可以。如果我们不加判断,当返回给文本阅读器一张图片时,可能它显示的就是乱码。
Accept-Encoding: 例: Accept-Encoding:gzip, deflate, br 表示客户端所支持的解码(解压缩)格式。
网路数据的传输都是占据带宽的,而将文件数据压缩能够降低数据量,减少传输时间。所以服务器在返回数据给客户端时,常常对数据进行压缩(对用户透明,通常由服务器或代理来做),而压缩的方式有多种,到底采用哪一种则需要看客户端支持哪种解码方式,这时候就可以根据header中Accept-Encoding的值。
文件或数据的压缩,由服务器或代理来做,一般不需要程序员干预;客户端接收到数据时解压缩,通常由浏览器自动完成,对用户透明。 对于我们主动发起的ajax请求,一般数据量较少,不需要设置该字段。
Accept-Language: 例 Accept-Language:zh-CN,zh;q=0.9 表示客户端支持的语言格式(不是编码格式),如中文/英文,通常浏览器直接发起请求时,浏览器会根据被设置的语言环境(默认语言),来附加上该字段。
一般我们服务器解析报文时,是不理会该字段的。 他的使用场景可以是这样的,假如有个文件,有各种语言的版本,这样当不同请求发来时,我们可以根据Accept-Language的值来判断到底返回哪种语言版本给客户端。 (其实这种应用场景也一般不采用判断Accept-Language字段的方法,不靠谱,还不如直接在url中体现语言版本呢)
Accept-Charset: 例: Accept-Charset:gbk,utf-8;q=0.8 表示客户端支持编码格式。服务器在返回报文时,需要将字符按照一定的编码格式转换为字节序列发送给客户端,那么该采用哪种编码格式呢? 当然作为服务器端,他可以采用任何一种编码方式,客户端都得完完整整的接收响应报文。因为目前客户端几乎都支持常见编码类型,所以服务器在返回数据时,只需要按照既定的编码方式编码,然后在响应报文中告知客户端所使用的编码方式。这样客户端在接收到报文后按照该方式进行解码,就就不会出现乱码问题。
但是,如果客户端已经定了就使用某种解码方式,那么这时候服务器端就不能那么任性了,他就需要解析Accept-Charset字段,根据这个值,来设定采用的编码方式。 如上例中,以逗号分隔,客户端支持两种编码方式,gbk和utf-8(gbk优先级高于utf8),其中utf-8后的q值,表示utf-8占的“权重”。
题外话: 服务器端怎么通知浏览器所采用的编码格式呢? 如果不通知浏览器,那么浏览器会采用什么样的格式解码呢?服务器端以原生的Servlet & JSP为例: 1)当返回的是HTML页面,那么页面meta charset就指定了编码格式 2)当返回的是JSP页面,那么页面pageEncoding就指定了编码格式 3)当通过resp的Outputstream返回原生内容时,我们可以通过设置响应头content-type/content-charset字段来指定编码格式
那么如果服务器不指定编码格式呢? 我的测试环境为win10中文操作系统,浏览器:Chrome 64.0.3282.186(正式版本)
1)返回的html页面不设置meta标签,但是文件本身是utf-8或gbk编码,中文不乱码, 服务器会将html页面转换为字节流写给浏览器,浏览器读取字节流,由于找不到meta标签设置的文件格式,就会按照默认的格式解码。
这时出现的情况是,当原页面是gbk编码时,浏览器能正常显示页面;当原页面是utf-8编码时,浏览器显示中文乱码。
这说明当前Chrome浏览器的默认编码格式为gbk。使用微软自带的Microsoft Edge测试结果一样 。
2)返回JSP页面时,必须指定pageEncoding。
3)通过response的输入流,直接返回生成的字节流(GBK格式的),此时,不设置响应头的编码格式。
@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//resp.setContentType("text/html;charset=gbk"); resp.setContentType("text/html;"); ServletOutputStream out = resp.getOutputStream(); out.write("<h1>好好学习</h1>".getBytes("gbk")); out.close();
}123456789101、直接在浏览器地址栏输入访问地址,不乱码
2、通过ajax发送get请求,乱码
var xhr = new XMLHttpRequest();xhr.onload = function (argument) { if(xhr.readyState==4){ alert(xhr.responseText);//打印接收的字符串 }}xhr.open('get','http://localhost:8080/mvctest/http',true);xhr.send(null);12345678
当服务器使用gbk编码返回字节流时,地址栏的http请求不乱码,但是ajax请求响应乱码; 如果我们的服务器使用utf-8返回字节流时,地址栏的http请求乱码,但是ajax不乱码。 (第二种测试结果贴图省略)
这说明同一个浏览器,在不同的地方采用的编码格式不同,当浏览器解析页面时,它默认使用的是gbk编码(可能因为我们的中文操作系统,同时是中文版的软件,所以浏览器默认使用gbk格式来解析页面);当浏览器使用内核XMLHttpRequest对象来解析响应时,默认采用的是utf-8(这个应该跟操作系统语言没关系,内核层面的应该在哪个国家都一样)
所以,如果为了确保在各种情况下都不乱码,服务器一定要通知客户端所采用的编码格式我们继续来说头字段的含义:
Referer: 例: Referer:http://localhost:8080/test/11.html 表示当前请求是从哪个资源发起的;或者是请求的上一步的地址。 我在11.html页面发起一个请求,这时候浏览器封装的请求头就有上例中的referer字段,表示当前请求是这个资源链接中发起的。
Referer是常用于网站的访问统计,比如我在很多地方都做了广告链接到我网站的主页,这时候我就可以通过Referer来查看哪些地方跳转过来的人多,就说广告的效果好。 另外,Referer还经常用于防盗链,具体可以参见这位兄台博客“http防盗链”
If-Modified-Since: 例: If-Modified-Since:Thu, 29 Mar 2018 08:37:45 GMT 表示客户端缓存文件的时间。字面翻译的意思是,“如果从…时间改变了”(就请再发送给我一遍新的文件)。
当客户端访问服务器的静态文件时,通常会将资源结果缓存下来,并标记一下文件的缓存时间(根据响应头中的Last-Modified字段);当接下来再发送同样的请求时,会在请求头中添加上这个字段If-Modified-Since;
服务器端读取字段值,判断服务器端文件的最后修改时间,如果如果不晚于该值,说明浏览器缓存的文件是最新的,然后就不会重新发送文件内容,而是将相应报文的状态设置为304,表示你读取缓存的文件就可以了,这就很大程度上节省了带宽。 第一次请求头:
GET /mvctest/11.html HTTP/1.1Host: localhost:8080Connection: keep-aliveUpgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8Accept-Encoding: gzip, deflate, brAccept-Language: zh-CN,zh;q=0.912345678第一次响应头:
第二次请求头: 第二次响应头:
需要说明的是,If-Modified-Since字段的值,为服务器端文件最后修改的时间,不是请求的访问时间,时间值为GMT格林尼治时间,不是本地时间。 浏览器一般只对.html,.jpg,.css,.js等这些静态资源进行缓存,对于jsp页面以及ajax请求的动态结果,不缓存。服务器如Tomcat会自动给静态文件的响应报文添加“Last-Modified”字段,同时解析请求报文中的If-Modified-Since字段,这些都是对我们透明的。
例如,我们将11.html改为11.jsp,那么浏览器将不会缓存页面内容,服务器每次都响应一个完整的页面内容给客户端,也不会在响应报文中添加“Last-Modified”字段。 每次对于JSP请求的响应结果:
If-None-Match: 例: If-None-Match:W/”607-1522312665174” 该字段同If-Modified-Since字段一样,都是用来表示资源文件是否是最新的。只不过If-Modified-Since的值为文件的最后修改时间,而该值为资源实体的哈希值,同样是由服务器生成的。 从上面的截图中我们可以看到: 第一次请求时,服务器的响应报文中有字段Etag,这就是实体的哈希值,浏览器会缓存文件并记录该值。 第二次请求时,请求头字段中就有If-None-Match,值为Etag的值,而服务器会判断该值与服务器中文件的哈希值是否相同,如果相同,就返回304,让浏览器读取缓存;否则会返回新的资源文件,并在响应头中设置新的Etag值。
Last-Modified/If-Modified-Since 和 Etag/If-None-Match这两对头字段都是来标记缓存资源的,但是后者的优先级要高于前者。
Cache-Control: 例: Cache-Control:no-cache 字段的字面意思为“缓存-控制”,前面我们将了几个字段表面客户端/服务器如何使用缓存机制,而这个字段就是用来控制缓存的。
Cache-Control在请求/响应报文头中均可设置,分别表明不同的意思,下面我们以响应报文为例:cache-control在响应报文的的取值可以为:public、private、no-cache、no- store、no-transform、must-revalidate、proxy-revalidate、max-age。 所代表的意思为:
其中,no-cache、no-store、max-age为常用的取值。 比如,服务器在响应报文中添加Cache-Control:no-store,表示浏览器或各级代理,不要缓存本次的相应内容(即使响应报文中有Etag和Last-Modified);
比如,响应报文中有Cache-Control:no-cache,表示浏览器可以缓存响应文件,但是在使用缓存之前,必须通过令牌(Etag)来与服务器进行沟通确认缓存有效。
比如,响应报文中有Cache-Control:max-age=500,表示在接下来的500秒内,浏览器可以自主使用缓存内容,不需要向服务器发送同样的请求。
在请求报文中,也可以添加cache-control字段,其取值可以为no-cache、no-store、max-age、 max-stale、min-fresh、only-if-cached。 客户端在发送请求到服务器时,可能会经过很多层代理,而这些代理可能就缓存了本次请求想要的文件,而请求中的cache-control就可以控制,是否使用代理中的缓存文件。
比如,请求报文头中有cache-control:no-cache,那就表示,代理如果返回给我缓存文件时,需要到服务器端进行确认,缓存是不是最新的。
比如,请求报文头中有cache-control:no-store,那就表示,我不需要代理中的缓存文件,我需要直接请求服务器。
所以我们可以看到,cache-control就是用来控制缓存使用的,如是否缓存,是否使用缓存,缓存到期时间等,而Last-Modified/If-Modified-Since 和 Etag/If-None-Match是标识C/S之间怎么使用缓存。 缓存的使用都是服务器和客户端的默认行为,对用户和程序员的透明的,当然我们可以通过配置文件或程序修改他们的行为规则。 附:http协议中对缓存的说明
User-Agent: 例: User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36 表示客户端的软件环境。如上可以看出使用的是Window10 64位操作系统,Chrome浏览器等信息。服务器可以根据该字段评估客户端的环境从而给出不同的响应。(比如根据请求是从手机端或是电脑端发起的,返回不同版本的页面)
Host: 例: Host:localhost:8080 表示请求者的主机地址(IP地址)和端口号。 服务器端可以根据该字段进行ip过滤等操作。
响应头 Etag、Last-Modified、cache-control在前文中已经说明。
Content-Length: 例: Content-Length:607 表示接收到的响应报文的总长度为607。 根据这个长度,客户端可以更准确的接收和解析报文内容。或者可以根据当前接收/解析的长度占总长度的百分比,做出进度条的效果。
Accept-Ranges: 例: Accept-Ranges:bytes 表示服务器支持http中的Range功能,能够分段请求客户端能够分段请求服务器。 我们上网时常用的“断点续传”,或者服务器所谓的“多线程下载”就是靠的服务器端的Range技术。 Range功能的请求-响应流程如此: 客户端发起带range的请求:
GET /test.rar HTTP/1.1Connection: closeHost: 116.1.219.219Range: bytes=0-1001234在头中添加Range字段,表示我要请求[0-100]这101个字节的数据。 此处Range的值,可以添加多个片段,如 Range:bytes=0-100,200-300等。
服务器响应报文:
HTTP/1.1 206 OKContent-Length: 801 Content-Type: application/octet-stream Content-Location: http://www.onlinedown.net/hj_index.htmContent-Range: bytes 0-100/2350 //2350:文件总大小Last-Modified: Mon, 16 Feb 2009 16:10:12 GMTAccept-Ranges: bytesETag: "d67a4bc5190c91:512"Date: Wed, 18 Feb 2009 07:55:26 GMT123456789响应报文中有Content-Range字段,表示响应的报文片段内容范围,已经总的数据大小。 同时Range请求的正常的返回码是206,不是200。
而即使我们请求的不是Range功能请求,那么服务器的返回字段中会有Accept-Range,表示服务器支持Range功能。
Server: 例: Server: Apache/2.4.1 (Unix) 表示服务器的名称,是Unix下的Apache服务器--------------------- 作者:Boboma_dut 来源:CSDN 原文:https://blog.csdn.net/Boboma_dut/article/details/79741162 版权声明:本文为博主原创文章,转载请附上博文链接!