http请求报文
- http请求信息由三部分组成
- 请求方法 URI协议 http版本
- 请求头(Request Header)
- 请求正文
例子:
GET /sample.jsp HTTP/1.1 Accept:image/gif.image/jpeg,*/* Accept-Language:zh-cn //客户端所用的语言 Connection:Keep-Alive Host:localhost //主机名 User-Agent:Mozila/4.0(compatible;MSIE5.01;Window NT5.0) //浏览器版本 Accept-Encoding:gzip,deflate
- 其中URI:URI为/sample.jsp;URI完整地指定了要访问的网络资源,通常只要给出相对于服务器根目录的相对目录即可,因此以“/”开头。
- 另外URL:统一资源定位符;<协议>://<主机>:<端口>/<路径>?<参数>
其中请求头:请求头包含许多有关的客户端环境和请求正文的有用信息。例如,请求头可以声明浏览器的版本、所用的语言、请求正文的长度等。
- Accept:客户端可识别的内容类型列表
Content-Type: 标识向服务器发送的数据的格式。格式:type/subtype(;parameter:type).
Content-Type:text/html;charset:utf-8
在html页面中可以通过下面的方式指定
这种方式可以指定很多种媒体类型,但是不能指定application/x-www-form-urlencoded和multipart/form-data这两种类型
这种方式可以指定两种类型
Cookie:通知服务器当前页面的域生效中的Cookie
请求正文:get没有请求正文。请求正文与请求头之间是一个空行,请求正文中包含客户端提交的字符串信息
username=jinqiao&password=1234
- get、post的选择
- get请求纯粹取得资源,例如查询数据库的数据。
- post请求可能会影响服务器上的数据或状态,例如增删改。
http响应
- http响应也由三个部分构成:
- 状态行
- 响应头(Response Header)
- 响应正文
状态行
状态行由协议版本、状态码和相应的状态描述组成,各元素之间以空格分开
HTTP/1.1 200 OK
- 1xx: 指示信息——表示信息已接收,继续处理
- 2xx:成功——表示请求已被成功接收、理解并接受
- 3xx: 重定向
- 4xx: 客户端错误——请求有语法错误或请求无法实现
- 5xx: 服务器端错误——服务器未能实现合法的请求
- 比如:
- 200:OK,客户端请求成功
- 400:Bad Request,由于客户端请求有语法错误,不能被服务器所理解
- 401:Unauthonzed,请求未经授权。这个状态代码必须和WWW-Authenticate报头域一起使用。
- 403:Forbidden,服务器接收到请求,但是拒绝提供服务。服务器通常会在响应正文中给出不提供服务的原因。
- 404:Not Found,请求的资源不存在
- 500:Internal Server Error,服务器发生不可预期的错误,导致无法完成客户端的请求。
- 503:Service Unavailable,服务器当前不能够处理客户端的请求,在一段时间后可能会恢复正常。
响应头可能包括:
- Location响应报头域:当我们在jsp中使用重定向语句的时候,响应报头中就会有Location
- Server响应报头域:包含了服务器用来处理请求的软件信息,和User-Agent是相对应的。
WWW-Authenticate响应报头域:必须被包含在401响应消息中。当客户端收到401响应消息,就要决定是否请求服务器对其进行验证。如果要求服务器对其进行验证,就可以发送一个包含了Authorization报头域的请求,小面是WWW-Authenticate响应报头域的一个例子:可知服务器对我们所请求的资源采用的是基本验证机制。
WWW-Authenticate: Basic realm="Basic Auth Test!"
Content-Encoding实体报头域:媒体类型的修饰符,它的值指示了被应用到实体正文的附加内容编码,因为要获得Content-Type报头域中所引用的媒体类型,必须采用相应的解码机制
Content-Type:gzip
Content-Type实体报头域:指明发送给接收者的实体正文的媒体类型。
Content-Type: text/html;charset=ISO-8859-1
- Expires实体报头域:响应过期的日期和时间。通常,代理服务器或浏览器会缓存一些页面,当用户档次访问这些页面时,直接从缓存中加载并显示给用户,这样缩短了响应时间,减少服务器的负载。为了让代理服务器或浏览器在一段时间后更新页面,我们可以使用Expires指定页面过期的时间。当用户又一次访问页面时,如果Expires给出的日期比Date普通报头域给出的日期要早或相同的话,那么代理服务器或浏览器就不会再使用缓存的页面而是从服务器上请求更新的页面。HTTP1.1的客户端和缓存必须将除RFC 1123之外的日期格式和0看做已过期。例如,为了让浏览器不要缓存页面,我们设置Expires设置为0:response.setDateHeader(“Expires”,0);
- Cache-Control实体报头域:指定请求和相应遵循的缓存机制。请求时的缓存指令包括:no-cache,no-store,max-age,max-stale,min-fresh,only-if-cached;响应时的指令包括:
- Public指示响应可被任何缓存区缓存。
- Private指示对于单个用户的整个或部分响应消息,不能被共享缓存处理。这允许服务器仅仅描述当用户的部分响应消息,此响应消息对于其他用户的请求无效。
- no-cache指示请求或响应消息不能缓存
- no-store用于防止重要的信息被无意的发布。在请求消息中发送将使得请求和响应消息都不使用缓存。
- max-age指示客户机可以接收生存期不大于指定时间(以秒为单位)的响应。
- min-fresh指示客户机可以接收响应时间小于当前时间加上指定时间的响应。
- max-stale指示客户机可以接收超出超时期间的响应消息。如果指定max-stale消息的值,那么客户机可以接收超出超时期指定值之内的响应消息。
禁用缓存
response.setHeader("Pragma","no-cache"); response.addHeader( "Cache-Control", "no-cache" ); //作用与上一句相同,不过通常两者合用 response.setDateHeader("Expires", 0); //好像可以单独使用,不过通常也与上两句合用
- Set-Cookie:通知客户端保存如下cookie
- 请求和响应步骤
Cookie
- Cookie总是保存在客户端中,按在客户端中的位置可以分为:
- 内存Cookie:由浏览器维护,保存在内存中,浏览器关闭之后就消失,属于非持久Cookie
- 硬盘Cookie:保存在硬盘中,有一个过期时间,除非用户手动清理或到了过期时间,否则不会被删除,属于持久Cookie
- 用途:因为HTTP协议是无状态的,即服务器不知道用户上一次做了什么,这严重阻碍了交互式web应用程序的实现。Cookie就是用来绕开HTTP的无状态性的“额外手段”之一。
- 应用场景:当登录一个网站时,如果用户勾选“下次自动登录”,那么本次登录时,服务器就会发送包含登录凭据(用户名和密码的某种加密形式)的Cookie到用户的硬盘上。第二次登录时,浏览器会发送该Cookie到服务器,于是不必再输入用户名和密码就让用户登录了。
- 识别功能:如果在一台计算机中安装多个浏览器,每个浏览器都会以独立的空间存放Cookie。Cookie中不但可以确认用户信息,还包含计算机和浏览器的信息,所以一个用户使用不同的浏览器登录或不同的浏览器登录,都会得到不同的Cookie信息。
- 一般用来处理登录等场景,目的是让服务端知道谁发出的这次请求。如果你请求了接口进行登录,服务端验证通过后会在响应头加入set-cookie字段,然后下次再发请求的时候,浏览器会自动将cooker附加在请求的头字段cookie中,服务端就能知道这个用户已经登录过了。
url、域名
- uniform resource locator,统一资源定位符,俗称网址。
- 格式:<>://<ip或域名>:
/<路径>,其中,port和路径可以省略,这样的路径映射默认首页,如,https://www.baidu.com/。
域名
- Domain Name,网域名称,简称域名,是以文字形式记录的ip地址,理由是好记。
- 网域名称系统,DNS,用于将域名翻译成ip地址的系统。
- 一个ip地址可以对应多个域名,但是一个域名只有一个ip地址。
url编码
如果请求参数本身包括“=”等特殊字符怎么办?又或者你想发送的请求参数值时http://openhome.cc这个值呢?假设是get请求,则不能在地址栏上输入
http://openhome.cc/addBookmar.do?url=http://openhome.cc.
- URI中定义了一些保留字符,如,:/ ?& = @ %等。如果要在请求上表达这些字符,必须在%字符之后以十六进制数值表示方式,来表示该字符的八个位数值。这就是URI规范中的百分比编码,也即是URI编码或URL编码。
例如,字符“:”真正存储时的八位为00111010,必须使用%3A来表示;所以若发送的请求参数值是http://openhome.cc,则必须使用以下格式
http://openhome.cc/addBookmar.do?url=http%3A%2F%2Fopenhome.cc
如果想知道某个字符的URL编码是什么,在Java中可以使用java.net.URLEncoder类的静态方法encode()。;要译码则使用decode()
String text=URLEncoder.encode("http://openhome.cc", "utf-8");
- 不过在URI之前,HTTP也规定了请求中的保留字,这与URI规范有所差别。其中一个就是URI规范空格符为%20,而HTTP规范为“+”,上面java方法产生的字符串,空格的编码就为“+”。
- 由于中文不在ASCⅡ字符之中,所以不能直接出现在地址栏而应该写其编码。在URI规范的URL编码中,针对的是utf-8编码的八位数。在utf-8编码下,一个中文字符有三个编码。而在HTTP规范下的URL编码,并不限使用utf-8,比如使用big5编码,一个中文的编码为两个。
- 但其实在浏览器中我们是可以直接输入中文的,这是因为我们输入的中文被浏览器隐式转为编码了,只是表面上显示为中文而已