最近面试被问了一个HTTP控制缓存的问题和一个Http状态码的问题,没答上来。空闲时间看了一些关于HTTP的内容,记录一下。
什么是HTTP
-
HTTP是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。
-
基于TCP/IP通信协议从WEB服务器传输超文本到本地浏览器的传送协议。
-
HTTP使用统一资源标识符(Uniform Resource Identifiers, URI)来传输数据和建立连接。
HTTP请求(Request)与相应(Response)
请求(Request)
HTTP请求.png一次请求可以分为4个部分
- 请求行
用来说明请求类型,要访问的资源以及所使用的HTTP版本 - 请求头部
紧接着请求行(即第一行)之后的部分,用来说明服务器要使用的附加信息 - 空行
请求头部后面的空行是必须的 - 请求数据
也叫主体,可以添加任意的其他数据
HTTP有多种请求方式,最常见的是GET和POST以及HEAD
GET
- 请求的参数会附在URL之后。把数据放置在HTTP协议头中,以?分割URL和传输数据,多个参数用&连接
- 有长度限制
- 主要用于查询
POST
- 把提交的数据放置在是HTTP包的包体中
- 安全性较高
- 主要用于修改(提交)
HEAD
- HEAD 方法只是请求消息报头,而不是完整的内容。
- 通常被用于测试超链接的有效性,是否可以访问,以及最近是否更新。
响应(Response)
HTTP响应.jpg一次响应可以分为4个部分
- 状态行
由HTTP协议版本号, 状态码, 状态消息 三部分组成。 - 消息报头
用来说明客户端要使用的一些附加信息 - 空行
消息报头后面的空行是必须的 - 响应正文
服务器返回给客户端的文本信息
HTTP状态码
1xx:指示信息--表示请求已接收,继续处理
2xx:成功--表示请求已被成功接收、理解、接受
3xx:重定向--要完成请求必须进行更进一步的操作
4xx:客户端错误--请求有语法错误或请求无法实现
5xx:服务器端错误--服务器未能实现合法的请求
常见状态码:
200 OK //客户端请求成功
400 Bad Request //客户端请求有语法错误,不能被服务器所理解
401 Unauthorized //请求未经授权
403 Forbidden //服务器收到请求,但是拒绝提供服务
404 Not Found //请求资源不存在,eg:输入了错误的URL
500 Internal Server Error //服务器发生不可预期的错误
503 Server Unavailable //服务器当前不能处理客户端的请求,一段时间后可能恢复正常
HTTP请求过程
http请求过程.pngHTTP控制缓存
通过响应来控制缓存,在响应头中主要有cache-control、pragma、expires三个响应头,主要通过cache-control来控制缓存。cache-control是HTTP1.1中的响应头,其参数为相对的秒值,即过多少秒缓存失效,因此建议使用该响应头来控制缓存失效时间,其后可以跟的内容有no-cache、no-store、max-age、must-revalidate
Cache-Control的主要参数
- Cache-Control: private/public Public 响应会被缓存,并且在多用户间共享。 Private 响应只能够作为私有的缓存,不能再用户间共享。
- Cache-Control: no-cache:不进行缓存
- Cache-Control: max-age=x:缓存时间 以秒为单位
- Cache-Control: must-revalidate:如果页面是过期的 则去服务器进行获取。
注意:cache-control: no-cache控制缓存,客户端是会缓存资源的,只是在于原始服务器进行再验证之前不会想客户端提供资源,也就是资源新鲜度永远过期,这样比直接访问服务器节省了资源在网络中的传输成本,相比开启缓存增加了再验证的成本,性能失效介于两者之间;要想客户端缓存不从响应中拷贝资源副本,则应该使用cache-control: no-store,使用该响应头内容也可以让缓存立即删除已经拷贝的副本;而must-revalidate是服务器希望缓存能严格遵守过期信息,一般情况下类似no-cache,但在缓存与原始服务器进行新鲜度验证的时候,原始服务器不可用,这将会导致这一段时间中访问该资源会504 gateway timeout,因此建议使用no-cache
附上HTTP响应头参数
-
Allow
服务器支持哪些请求方法(如GET、POST等)。 -
Content-Encoding
文档的编码(Encode)方法。只有在解码之后才可以得到Content-Type头指定的内容类型。利用gzip压缩文档能够显著地减少HTML文档的下载时间。Java的GZIPOutputStream可以很方便地进行gzip压缩,但只有Unix上的Netscape和Windows上的IE 4、IE 5才支持它。因此,Servlet应该通过查看Accept-Encoding头(即request.getHeader("Accept-Encoding"))检查浏览器是否支持gzip,为支持gzip的浏览器返回经gzip压缩的HTML页面,为其他浏览器返回普通页面。 -
Content-Length
表示内容长度。只有当浏览器使用持久HTTP连接时才需要这个数据。如果你想要利用持久连接的优势,可以把输出文档写入 ByteArrayOutputStream,完成后查看其大小,然后把该值放入Content-Length头,最后通过byteArrayStream.writeTo(response.getOutputStream()发送内容。 -
Content-Type
表示后面的文档属于什么MIME类型。Servlet默认为text/plain,但通常需要显式地指定为text/html。由于经常要设置Content-Type,因此HttpServletResponse提供了一个专用的方法setContentType。 -
Date
当前的GMT时间。你可以用setDateHeader来设置这个头以避免转换时间格式的麻烦。 -
Expires
应该在什么时候认为文档已经过期,从而不再缓存它? -
Last-Modified
文档的最后改动时间。客户可以通过If-Modified-Since请求头提供一个日期,该请求将被视为一个条件GET,只有改动时间迟于指定时间的文档才会返回,否则返回一个304(Not Modified)状态。Last-Modified也可用setDateHeader方法来设置。 -
Location
表示客户应当到哪里去提取文档。Location通常不是直接设置的,而是通过HttpServletResponse的sendRedirect方法,该方法同时设置状态代码为302。 -
Refresh
表示浏览器应该在多少时间之后刷新文档,以秒计。除了刷新当前文档之外,你还可以通过setHeader("Refresh", "5; URL=http://host/path")让浏览器读取指定的页面。
注意这种功能通常是通过设置HTML页面HEAD区的<META HTTP-EQUIV="Refresh" CONTENT="5;URL=http://host/path">实现,这是因为,自动刷新或重定向对于那些不能使用CGI或Servlet的HTML编写者十分重要。但是,对于Servlet来说,直接设置Refresh头更加方便。
注意Refresh的意义是"N秒之后刷新本页面或访问指定页面",而不是"每隔N秒刷新本页面或访问指定页面"。因此,连续刷新要求每次都发送一个Refresh头,而发送204状态代码则可以阻止浏览器继续刷新,不管是使用Refresh头还是<META HTTP-EQUIV="Refresh" ...>。
注意Refresh头不属于HTTP 1.1正式规范的一部分,而是一个扩展,但Netscape和IE都支持它。 -
Server
服务器名字。Servlet一般不设置这个值,而是由Web服务器自己设置。 -
Set-Cookie
设置和页面关联的Cookie。Servlet不应使用response.setHeader("Set-Cookie", ...),而是应使用HttpServletResponse提供的专用方法addCookie。参见下文有关Cookie设置的讨论。 -
WWW-Authenticate
客户应该在Authorization头中提供什么类型的授权信息?在包含401(Unauthorized)状态行的应答中这个头是必需的。例如,response.setHeader("WWW-Authenticate", "BASIC realm=\"executives\"")。
注意Servlet一般不进行这方面的处理,而是让Web服务器的专门机制来控制受密码保护页面的访问(例如.htaccess)。
网友评论