Http 协议详解 学习笔记
?
?
?
??
?
5、HTTP请求的细节——请求行?
?
????请求行中的GET称之为请求方式,请求方式有七种:POST、GET、HEAD、OPTIONS、DELETE、TRACE、PUT。而常用的有两种:?GET?方式、?POST?方式。用户如没有设置,默认情况下浏览器向服务器发送的都是get请求,例如在浏览器直接输地址访问,点超链接访问等都是get,用户如想把请求方式改为post,可通过更改表单的提交方式实现。
?
????不管POST或GET,都用于向服务器请求某个WEB资源,这两种方式的区别主要表现在数据传递上:
?
????????a.如请求方式为GET方式,则可以在请求的URL地址后以?的形式带上交给服务器的数据,
?
????????????多个数据之间以&进行分隔,例如:?GET?/mail/1.html?name=abc&password=xyz?HTTP/1.1
?
????????????GET方式的特点:在URL地址后附带的参数是有限制的,其数据容量通常不能超过1K。
?
????????b.如请求方式为POST方式,则可以在请求的实体内容中向服务器发送数据.
?
????????????Post方式的特点:传送的数据量无限制。
?
?
?
?
6、HTTP请求的细节——常用消息头
?
????用于HTTP请求中的常用头:告诉服务器,浏览器的当前工作环境信息。
?
??????Demo样例:
?
????????Accept:?text/html,image/*????
?
????????Accept-Charset:?ISO-8859-1
?
????????Accept-Encoding:?gzip,compress
?
????????Accept-Language:?en-us,zh-cn?
?
????????Host:?www.it315.org:80
?
????????If-Modified-Since:?Tue,?11?Jul?2000?18:23:51?GMT
?
????????Referer:?http://www.it315.org/index.jsp
?
????????User-Agent:?Mozilla/4.0?(compatible;?MSIE?5.5;?Windows?NT?5.0)
?
????????Cookie:
?
????????Connection:?close/Keep-Alive???
?
????????Date:?Tue,?11?Jul?2000?18:23:51?GMT
?
?????
?
????请求头详解:
?
????????Accept:?用于告诉服务器,客户机所支持的数据类型
?
????????Accept-Charset:?用于告诉服务器,客户机所采用的码表
?
????????Accept-Encoding:?用于告诉服务器,客户机所支持的数据压缩格式
?
????????Accept-Language:?用于告诉服务器,客户机的语言环境
?
????????Host:?用于告诉服务器,客户机想访问服务器哪台主机
?
????????If-Modified-Since:?用于告诉服务器,客户机对于资源的最后缓存时间,精确到秒级。
?
????????Referer:?用于告诉服务器,客户机是从哪个页面去访问服务器的??(防盗链)
?
????????User-Agent:?用于告诉服务器,客户机的机器环境(例如所使用的操作系统,浏览器版本号)
?
????????Cookie:客户端通过这个头字段,可以带一些数据给服务器
?
????????Connection:客户端通过这个头字段告诉服务器,请求完成后,是保持链接还是关闭链接
?
?????
?
?
?
?
?
?
7、HTTP响应?概述
?
????一个HTTP响应代表服务器向客户端回送的数据,它包括:
?
????一个状态行、若干消息头、以及实体内容?。?
?
?
?
?
?
?
?
?
?
8、HTTP响应的细节——状态行
?
????状态行
?
??????格式:?HTTP版本号 状态码 原因叙述<CRLF>
?
??????举例:HTTP/1.1?200?OK
?
????状态码用于表示服务器对请求的处理结果,它是一个三位的十进制数。响应状态码分为5类,如下所示:
?
?
?
?
?
?
?
?
9、HTTP响应细节——常用响应头?
?
????HTTP请求中的常用响应头
?
?????Demo样例:
?
????????Location:?http://www.sina?.org/index.jsp?
?
????????Server:apache?tomcat
?
????????Content-Encoding:?gzip?
?
????????Content-Length:?80?
?
????????Content-Language:?zh-cn?
?
????????Content-Type:?text/html;?charset=GB2312?
?
????????Last-Modified:?Tue,?11?Jul?2000?18:23:51?GMT
?
????????Refresh:?1;url=http://www.sina.org
?
????????Content-Disposition:?attachment;?filename=aaa.zip
?
????????Transfer-Encoding:?chunked??
?
????????Set-Cookie:SS=Q0=5Lb_nQ;?path=/search
?
????????ETag:?W/"7777-1242234904000"
?
????????Expires:?-1
?
????????Cache-Control:?no-cache??
?
????????Pragma:?no-cache???
?
????????Connection:?close/Keep-Alive???
?
????????Date:?Tue,?11?Jul?2000?18:23:51?GMT
?
??????
?
????响应头详解
?
????????Location:这个头通常配合302状态码使用,服务器使用这个头告诉浏览器去找谁【范例见Demo1】
?
????????Server:服务器通过这个头告诉浏览器,服务器的类型
?
????????Content-Encoding:?服务器通过这个头告诉浏览器,数据的压缩格式(gzip)?【范例见Demo2】?
?
????????????????一定要压缩服务器返回数据,既可提升服务器性能,又可大大减少服务器网络流量费用
?
????????Content-Length:服务器通过这个头告诉浏览器,回送数据的长度【范例见Demo2】?
?
????????Content-Language:?服务器通过这个头告诉浏览器,回送数据的语言;??
?
????????Content-Type:?服务器通过这个头告诉浏览器,回送数据的类型【范例见Demo3】?
?
??????????????????对于响应返回图片、视频、音频等数据类型时,很重要。
?
????????Last-Modified:?服务器通过这个头告诉浏览器,数据的最后修改时间,精确到秒级。
?
????????Refresh:服务器?告诉浏览器,多长时间定时刷新或定时转向其他页面?(论坛刷新)【范例见Demo4】?
?
????????Content-Disposition:?控制浏览器以下载方式打开回送的数据【范例见Demo5】?
?
????????????????????对于响应返回图片、视频、音频等数据类型时,可能会用到。
?
????????Transfer-Encoding:?服务器通过这个头告诉浏览器,数据是以块方式回送的(用的少)
?
???????
?
????????Expires:控制浏览器缓存数据的时间(-1或0,代表控制浏览器不要缓存)
?
??????????????时间+数据:保存该数据缓存的时间,eg:2012?12?12?(1.html)?????
?
????????Cache-Control:?no-cache??
?
????????Pragma:?no-cache??
?
????????以上三个头一起用,就可以控制所有的浏览器不要缓存数据?
?
????????ETag:缓存相关,服务器给每一个网页都生成一个编码,用来进行比对,以配合304或307通知浏览器是否使用缓存的数据,精确到毫秒级。(一般的服务器不需要这么严谨)
?
?
?
?
?
?
10、Http请求常用响应头信息范例Demo?
?
????public?class?ServletDemo1?extends?HttpServlet?{
?
??????public?void?doGet(HttpServletRequest?request,?HttpServletResponse?response)
?
??????????throws?ServletException,?IOException?{
?
????????test5(response);
?
??????}
?
?????
?
????【范例Demo1:Location???】?
?
????????//指示浏览器重新定向
?
??????public?void?test1(HttpServletResponse?response){
?
????????response.setStatus(302);
?
????????response.setHeader("location",?"/day04/index.jsp");
?
??????}
?
?????
?
????【范例Demo2:Content-Encoding???】?
?
?????????//?演示数据压缩
?
??????public?void?test2(HttpServletResponse?response)?throws?IOException{?
?
????????String?data?=?"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";????//数据太小可能会压缩后反而更大,当数据大时压缩效果才显著。
?
???????
?
???????System.out.println("原始数据的大小:"?+?data.getBytes().length);
?
?????????//下面代码是压缩数据。GZIPOutputStream?是JDK自带的gzip压缩工具类,需要将数据写入流中
?
????????ByteArrayOutputStream?bout?=?new?ByteArrayOutputStream();
?
????????GZIPOutputStream?gout?=?new?GZIPOutputStream(bout);
?
????????gout.write(data.getBytes());
?
????????gout.close();
?
?????
?
????????byte?gzipData[]?=?bout.toByteArray();???//获得gzip压缩后的数据
?
????????response.setHeader("Content-Encoding",?"gzip");??//告诉浏览器压缩数据的格式
?
????????response.setHeader("content-length",?gzipData.length+"");??//数据大小
?
????????response.getOutputStream().write(gzipData);??//返回浏览器
?
??????}
?
?????
?
????【范例Demo3:Content-Type???】?
?
?????//content-type头字段的作用
?
??????public?void?test3(HttpServletResponse?response)?throws?IOException{?
?
????????????String?path?=?this.getServletContext().getRealPath("/02.jpg");
?
????????????FileInputStream?in?=?new?FileInputStream(path);
?
????????????byte?buffer[]?=?new?byte[1024];
?
????????????int?len?=?0;??
?
????????????response.setHeader("content-type",?"image/jpeg");//此语句要在写数据前执行
?
????????????OutputStream?out?=?response.getOutputStream();
?
????????????while((len=in.read(buffer))>0){
?
????????????????out.write(buffer,?0,?len);
?
????????????}
?
????????????out.close();
?
????????????in.close();
?
??????}
?
?????
?
????【范例Demo4:Refresh??】?
?
??????//控制浏览器定时刷新
?
??????public?void?test4(HttpServletResponse?response)?throws?IOException{?
?
????????response.setHeader("refresh",?"3;url='http://www.sina.com'");
?
????????response.getWriter().write("你的页面??3?秒钟后将会转向新浪首页");
?
??????}
?
?????
?
?????【范例Demo5:Content-Disposition??】?
?
??????//控制浏览器下载
?
??????public?void?test5(HttpServletResponse?response)?throws?IOException{?
?
????????response.setHeader("content-disposition",?"attachment;filename=02.jpg");?
?
????????String?path?=?this.getServletContext().getRealPath("/01.jpg");
?
????????FileInputStream?in?=?new?FileInputStream(path);
?
????????byte?buffer[]?=?new?byte[1024];
?
????????int?len?=?0;
?
????????OutputStream?out?=?response.getOutputStream();
?
????????while((len=in.read(buffer))>0){
?
??????????out.write(buffer,?0,?len);
?
????????}
?
????????out.close();
?
????????in.close();?
?
??????}
?
?????
?
??????public?void?doPost(HttpServletRequest?request,?HttpServletResponse?response)
?
??????????throws?ServletException,?IOException?{
?
????????doGet(request,?response);
?
??????}?
?
????}
?
?
?
?
11、HTTP其他实用头字段?及其Demo?
?
??????HTTP请求头字段
?
????????Range头指示服务器只传输一部分Web资源。这个头可以用来实现断点续传功能。
?
????????????Range字段可以通过三种格式设置要传输的字节范围:
?
????????????????Range:?bytes=1000-2000???:??传输范围从1000到2000字节。
?
????????????????Range:?bytes=1000-???????:??传输Web资源中第1000个字节以后的所有内容。
?
????????????????Range?bytes=1000??????????:??传输最后1000个字节。
?
????????由于浏览器并不支持该头字段,所以需要自己写客户端程序来实现该字段的功能。
?
????HTTP响应消息头字段
?
????????Accept-Ranges:这个字段说明Web服务器是否支持Range,
?
????????????支持则返回Accept-Ranges:?bytes,
?
????????????如果不支持,则返回Accept-Ranges:?none.
?
????????Content-Range:指定了返回的Web资源的字节范围。这个字段值的格式是:
?
????????????例子:?Content-Range:1000-3000/5000
?
?
?
????Demo样例:
?
????public?class?DownLoad?{
?
??????public?static?void?main(String[]?args)?throws?Exception?{?
?
????????URL?url?=?new?URL("http://localhost:8080/day04/1.txt");
?
????????HttpURLConnection?conn?=?(HttpURLConnection)?url.openConnection();?
?
????????conn.setRequestProperty("Range",?"bytes=6-");
?
????????FileOutputStream?out?=?new?FileOutputStream("c:\\1.txt",true);
?
????????InputStream?in?=?conn.getInputStream();
?
????????int?len?=?0;
?
????????byte?buffer[]?=?new?byte[1024];
?
????????while((len=in.read(buffer))>0){
?
??????????out.write(buffer,?0,?len);
?
????????}
?
????????in.close();
?
????????out.close();
?
??????}?
?
????}
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?