zoukankan      html  css  js  c++  java
  • Http协议

      对于一个浏览器,如果它要访问web资源,那就要通过HTTP协议来访问。

      一个高级程序员,那么他肯定对于Http相应有很深的理解,可以这么说“如果你不理解HTTP协议,那你就不用学web程序了;如果你非常了解HTTP协议,那你也不用学web了,因为什么,因为web程序就那么点东西”,下面开始介绍HTTP协议。

      HTTP协议总体来说一共分为两大类,1.请求头 2.响应头,

      一.先说请求头:

      

      请求行:GET是以get方式请求,请求的资源是/lav/1.html,HTTP的版号是1.1,http协议一共有两个版本号,分别是http1.0和http1.1,

      消息头:

        1.Accept:用来告诉服务器,客户端支持的数据类型,这里是全支持,举个例子:text/html,images

        2.Accept-Charset:用于告诉服务器,客户端采用的编码方式,例如:ISO-8859-1

        3.Accept-Encoding:用于告诉服务器,客户机支持的数据压缩格式,这里是gzip格式

        4.If-Modified-Since:用于告诉服务器,这是最后一次的缓存时间,一般的情况下,浏览器第一次在访问页面的时候会本地缓存,这个字段可根据服务最后一次更新的时间来比对,是否重新加载。

        5.Accept-Lanaguage:客户机的语言环境,可用作本地化。

        6.Host:客户机通过这个头告诉服务器,想访问那台主机。

        7.Referer:客户机通过这个头告诉服务,它是从那个资源来访问服务器的(用这个referer可以做“防盗链”),防盗链是什么,比如从别人的网站点击我的网站资源,在这种情况下可以避免直接的打开或者下载,一般情况下应用这个防盗链调回我网站的首页。

        8.User-Agent:客户机通过这个来告诉服务器,客户机的软件环境。

        9.Cookie:客户机通过这个头向服务器带给一些信息。

        10.Connection:客户机通过这个头来确定我这次请求完成,连接是否关闭。(close/Keep-Alive).

      以上就是消息头主要常用的几个头,还有很多,我们只说常用的。

      二.在说响应头:

       

      状态行:http协议的版本号,200状态码,原因叙述

          状态码

          100-199——————表示成功接受请求,要求客户端继续提交下一次请求才能完成整个的处理过程

          200-299——————表示成功接受请求,并已完成整个的处理过程

          300-399——————未完成请求,客户需要进一步细化请求,例如请求的资源已经移动一个新的地址,302(你请求,我要你去找别人),304和307要客户机去拿缓存。

          400-499——————客户端请求有错误,

          500-599——————服务器端出现错误

      多个响应头:

        Location:这个头配合302状态码使用,用于告诉客户机去找谁

        Server:服务器通过这个头告诉浏览器服务器的类型

        Content-Encoding:服务器通过这个头告诉浏览器,我要的数据压缩格式

        Content-Length:服务器通过这个头,告诉浏览器回送数据压缩的长度

        Content-Type:服务器通过这个头告诉浏览器回送数据的类型

        Last-Modified:用来告诉浏览器缓存时间。

        Transfer-Encoding:告诉浏览器数据的传送方式

        refresh:控制浏览器多长时间刷新一次(股票,聊天室)

        content-disposition:服务器通过这个头告诉浏览器数据以下载方式打开数据

        Etag: 和缓存相关的头,这个能保证"实时更新",用在对实时更新要求比较高的网站

        Expires:服务器通过这个头告,诉浏览器回送的资源缓存多上时间,-1,0代表不缓存,date

        cache-control: no cache 和 Pragma: no cache :服务器通过这个两个头告,诉浏览器不要缓存数据

          如果你想市面上的所有的浏览器不缓存你的数据,Expires,cache-control,Pragma都写上就可以了。

       未完待续---21:33

        下面代码演示,看一看响应头有什么作用,这里面我把测试代码都放在了方法里,如果你想测试别的,复制,或者引用都行,

        

      1 package com.du.servlet;
      2 
      3 import java.io.ByteArrayOutputStream;
      4 import java.io.File;
      5 import java.io.FileOutputStream;
      6 import java.io.IOException;
      7 import java.io.InputStream;
      8 import java.io.OutputStream;
      9 import java.io.PrintWriter;
     10 import java.util.zip.GZIPOutputStream;
     11 
     12 import javax.servlet.ServletException;
     13 import javax.servlet.http.HttpServlet;
     14 import javax.servlet.http.HttpServletRequest;
     15 import javax.servlet.http.HttpServletResponse;
     16 
     17 public class ServletDemo1 extends HttpServlet {
     18 
     19     public void destroy() {
     20         super.destroy(); 
     21         
     22     }
     23 
     24 
     25     public void doGet(HttpServletRequest request, HttpServletResponse response)
     26             throws ServletException, IOException {
     27          //把想测试的响应头代码放在doGet方法里  
     28     }
     29 
     30 
     31     /**
     32      * 让浏览器以什么方式打开数据,content-disposition
     33      * @param response
     34      * @throws IOException
     35      */
     36     private void test5(HttpServletResponse response) throws IOException {
     37         response.setHeader("content-disposition", "attachment;filename=duwenlei.png");
     38         
     39         InputStream in = this.getServletContext().getResourceAsStream("1.png");
     40         int len;
     41         byte[] buffer = new byte[1024];
     42         OutputStream out = response.getOutputStream();
     43         while((len = in.read(buffer)) > 0){
     44             out.write(buffer, 0, len);
     45         }
     46     }
     47 
     48 
     49     /**
     50      * 通过refresh头,来控制浏览器多长时间刷新一次
     51      * @param response
     52      * @throws IOException
     53      */
     54     private void test4(HttpServletResponse response) throws IOException {
     55         String data = "bbbbbbbbbbbbbbb";
     56         response.setHeader("refresh", "3");//3秒刷新一次
     57         // response.setHeader("refresh", "3;url='http://www.baidu.com'"); 三秒后跳转到百度,用于注册成功跳转首页效果
     58         response.getOutputStream().write(data.getBytes());
     59     }
     60 
     61 
     62     /**
     63      * 向网页写一张图片,通过Content-type告诉浏览器返回的数据类型
     64      * @param response
     65      * @throws IOException
     66      */
     67     private void test3(HttpServletResponse response) throws IOException {
     68         InputStream in = this.getServletContext().getResourceAsStream("1.png");
     69         int len;
     70         byte[] buffer = new byte[1024];
     71         //这个Content-Encoding 的类型在tomcat/conf/web.xml里存在,web.xml包含市面上
     72         //几乎所有的文件类型和对应的mime-type
     73         response.setHeader("Content-type", "image/png");
     74         OutputStream out = response.getOutputStream();
     75         while((len = in.read(buffer)) > 0){
     76             out.write(buffer, 0, len);
     77         }
     78     }
     79     
     80     /**
     81      * 利用状态码302,配合location实现重定向
     82      * @param response
     83      */
     84     public void test(HttpServletResponse response){
     85         response.setStatus(302);
     86         response.setHeader("location", "2.html");
     87     }
     88     
     89     /**
     90      * 通过Content-Encoding头和Content-Length,来实现浏览器识别gzip格式数据
     91      * 注意:这里的data的数据量要大一点,否则你会发现,数据一压反而大了
     92      * @param response
     93      * @throws Exception
     94      */
     95     public void test1(HttpServletResponse response) throws Exception{
     96         
     97         String data = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
     98         System.out.println("压缩前数据:" + data.getBytes().length + "字节");
     99         
    100         //byteArray往内存里写
    101         ByteArrayOutputStream bout = new ByteArrayOutputStream();
    102         
    103         //        (GZIPOutputStream)包装流————>写入————>底层流(bout)
    104         GZIPOutputStream gout = new GZIPOutputStream(bout);
    105         
    106         gout.write(data.getBytes());
    107         //这里有一个限制,包装流有一个缓冲,如果说你的数据没有放慢这个缓冲,
    108         //那么包装流就写不进底层流。怎么解决呢,很简单,我们把包装流关闭
    109         //他就可以写到底层流了
    110         gout.close();
    111         
    112         byte[] gzip = bout.toByteArray();   //得到压缩数据
    113         
    114         System.out.println("压缩后数据:" + gzip.length + "字节");
    115         
    116         //通知浏览器数据采用的压缩格式
    117         response.setHeader("Content-Encoding", "gzip");
    118         
    119         //这里还要通知浏览器数据的长度
    120         response.setHeader("Content-Length", gzip.length+"");
    121         
    122         //response.getOutputStream(),拿到浏览器的一个输出流,把压缩后的数据输出
    123         response.getOutputStream().write(gzip);
    124         
    125     }
    126 
    127 
    128     public void doPost(HttpServletRequest request, HttpServletResponse response)
    129             throws ServletException, IOException {
    130     }
    131 
    132     
    133     public void init() throws ServletException {
    134         
    135     }
    136 
    137 }

      这里有一个range头,用这个头来实现断点下载,我这里那出来单说,这个是Http请求头的字段,对于这个range头,你得要服务器支持才行

      tomcat5不支持,从tomcat6以后支持,所以,要检查下你的服务器支不支持。

      断点下载就是,如果浏览器下载一个文件,下载到一半,突然断网了,适用于这个情况,断网了,但是我们已经下载了一部分,当有网的时候,我们不可能在去重新的去下载这个文件,我们要接着继续下载这个文件以后的内容。

         range有三种格式来设置传输字节的范围

          1.range:bytes=1000-2000 传输从1000到2000字节

          2.range:bytes=1000-        传输web资源1000字节以后的所有内容

          3.range:bytes=1000    传输最后1000字节

      

     1 URL url = new URL("http://localhost:8080/day02/a.txt");
     2         //我们这里是http协议,所以我们要用HttpURLConnection
     3         HttpURLConnection conn = (HttpURLConnection) url.openConnection();
     4         //打开了连接我们要设置range请求头,我们这里假设已经往我的本地下载了5个字节
     5         //现在我们要下载5往后的数据
     6         conn.setRequestProperty("range", "bytes=5-");
     7         //拿到一个写入流
     8         InputStream in = conn.getInputStream();
     9         //这里要注意,我们之前已经下载了5个字节,现在要做的是在这5个字节后面追加
    10         //查api我们知道FileOutputStream(url,boolean),后面这个参数是问你是否
    11         //续写,默认是false,在这里改成打开
    12         FileOutputStream out = new FileOutputStream("E:\b.txt",true);
    13         
    14         //模版方法
    15         int len;
    16         byte[] buffer = new byte[1024];
    17         while((len = in.read(buffer)) > 0){
    18             out.write(buffer, 0, len);
    19         }
    20         in.close();
    21         out.close();

      ok,打完。 

    如果有使用请标明来源:http://www.cnblogs.com/duwenlei/
  • 相关阅读:
    react-custom-scrollbars的使用
    【react】Mobx总结以及mobx和redux区别
    【React】Redux入门 & store体验
    chrome安装react-devtools开发工具
    【vue】vuex防止数据刷新数据刷掉
    搭建博客的两个工具区别
    JavaScript中的作用域
    通过JavaScript创建表格
    JavaScript中的普通for循环和 for in循环
    JavaScript中创建默认对象的方式
  • 原文地址:https://www.cnblogs.com/duwenlei/p/3479051.html
Copyright © 2011-2022 走看看