• 阅读 图解HTTP ,读书笔记


    阅读它的目的只有一个:就是想了解客户端与服务端的通信是怎么实现的?

                  数据的存储是怎么实现的?

                  数据流通过程中遇到什么问题、返回什么状态、该怎么解决?

    • 网络基础 TCP / IP
    1.   通常使用的网络是在TCP/IP协议族的基础上运作的,而HTTP只是它内部的一个子集(如果想了解TCP/IP协议族的知识,请问Goole或度娘)。
    2.   分层管理,分层传输,客户端与服务端通过分层顺序进行通信,客户端从应用层往下走至服务端接收(请求过程)返过来也可以;
      1.   

        客户端  :   HTTP客户端 (应用层)  ->   TCP (传输层)  ->   IP (网络层)  ->  网络 (链路层)

                                             |

        服务端 :    HTTP服务端 (应用层)  <-   TCP (传输层)  <-   IP (网络层)  <-  网络 (链路层)

      2. 理解这个图的含义:客户端向服务端发出一个搜索某个数据的HTTP请求,为了传输方便,在传输层(TCP协议)把从应用层上收到的数据进行分割,并在各个报文上打上标记,端口号之类的,然后转发给网络层;在IP协议的网络层,指定目的地MAC地址;然后发往网络。至此,客户端的请求就准备齐全了。然后服务端接收到数据之后层层上报,一直到服务端的应用层,才算是真真接收到客户端传过来的数据请求。
    3.       负责传输的IP协议
      1. IP协议的作用是把各种数据包传给对方。而传送给对方需要满足一些条件,比如对方的IP地址、MAC地址(MAC地址就是网卡的固定地址)等,IP地址可以设置更换,而MAC地址基本不会更改。
      2. IP的通信依赖MAC地址。
      3. IP协议与IP地址
    4.    负责分割数据包的TCP协议
      1. 为了更容易的传输大数据,确保数据能够到达目标,TCP采用三次握手的分割数据方法把数据包送出去
    5.   负责域名解析的DNS服务
      1. DNS,提供域名到IP地址之间的解析服务,它是通过域名查找IP地址,或者是通过IP地址反查域名
    6.        URI   与   URL
      1. URI  统一资源标识符,在HTTP协议里,URI就是:http
      2. URL 资源的地点,URL是URI的子集,在充分理解URI的基础上,也可以使用URL替换URI
      3. URI的格式
        1. URI标识符                   http
        2. 登陆认证信息               可选项
        3. 服务器地址                  devapi.jiaj.com.cn
        4. 服务端端口                  8080
        5. 带层次的文件地址         jiajian-service-cms/api/v1/posts/friend/search
        6. 查询字符串                  ?createUserName=&startTime=&endTime=&page=1&size=10
        7. 示例:http://devapi.jiaj.com.cn:8080/jiajian-service-cms/api/v1/posts/friend/search?createUserName=&startTime=&endTime=&page=1&size=10
    • 简单的HTTP协议
    1. 通过请求和响应交换达成通信,客户端先发出请求,服务端收到请求后,作出响应,最后返回响应状态
    2. 客户端请求格式:请求方法(GET / POST / DELETE / PUT) + 请求URI + 协议版本 + 请求首部字段(可选) + 请求实体
    3. 服务端响应格式:协议版本 + 状态码 + 状态码状态 + 响应首部状态(可选)  + 返回实体
    4.  http是不保存状态的,不会持久保存上一次请求或响应的内容。如果需要比较久的保存这个客户端的请求状态、服务器的响应状态,就需要使用Cookie功能
    5. 如果不是访问特定的资源,而是对服务器本身发起请求,需要用  *   号来代替URI:   OPTIONS * HTTP / 1.1
    •  告知服务器意图的方法,就是客服端的请求方法:(增,删,改,查)
    1. GET           获取数据 用作查询 服务器响应返回状态
    2. POST         向服务端传输数据实体    用作新增、修改
    3. PUT           传输文件  同FTP,这个方法自身不带验证机制,存在安全问题,不建议使用
    4. HEAD        用作查询  获取请求报文的首部
    5. DELETE     删除数据  按请求URI删除指定的资源
    6. OPTIONS   向服务器询问支持什么方法,服务器返回,支持的方法
    7. TRACE       追踪路径  客户端通过TRACE方法可以查询发送过去的请求是怎么被加工修改的。这个方法容易引发跨站追踪攻击,不建议使用
    8. CONNECT  要求与代理服务器通信时,实现用遂道协议进行TCP通信  格式:  CONNECT  代理服务器名:端口号  HTTP版本

        

    •  HTTP1.0    与      HTTP1.1    支持的方法:
    1. GET            获取数据资源
    2. POST          传输数据实体
    3. DELETE      删除指定数据
    4. PUT            传输文件
    5. HEAD         获取报文首部
    6. OPTIONS    询问支持方法
    7. TRACE        追踪路径
    8. CONNECT   要求用遂道协议连接代理
    • 持久连接:  

              HTTP 1.1  中,所有的连接默认都是持久连接。HTTP 1.0没有实现。

              服务端不一定能够实现持久连接;

              客户端需要持久连接;

    • 使用Cookie,进行状态管理
    1.          Cookie技术是通过在请求和响应报文中写入cookie信息来控制客户端的状态
    2.          Cookie的使用,它的交互:
      1. 请求(这时没有cookie信息):GET 
      2. 响应(服务端生成cookie信息): 200 OK
      3. 再次请求(自动发送保存着的Cookie信息) :GET
      4. 设置cookie:       http://www.cnblogs.com/xiaochaohuashengmi/archive/2010/06/13/1757658.html
        1. cookie知识:     http://blog.csdn.net/fangaoxin/article/details/6952954
        2. cookie运行原理Cookie 会根据服务端发送的响应报文内的一个叫做 setCookie() 通知客户端保存 cookie。当客户端再向服务器发送请求时,这个请求会自动加入cookie。当服务端接收到客户端发来的带cookie的请求后,服务端会检查究竟是从哪一个客户端发来的连接请求,然后对比服务器上的记录,最后得到之间的状态信息。
      5. cookie 不提供修改、删除。如果要修改某个cookie,只需要新建一个同名的cookie,添加到response中覆盖原来的Cookie
    3.       设置cookie方法
      1. 第一种方法<script>
        //设置cookie
        function setCookie(cname, cvalue, exdays) {
            var d = new Date();
            d.setTime(d.getTime() + (exdays*24*60*60*1000));
            var expires = "expires="+d.toUTCString();
            document.cookie = cname + "=" + cvalue + "; " + expires;
        }
        //获取cookie
        function getCookie(cname) {
            var name = cname + "=";
            var ca = document.cookie.split(';');
            for(var i=0; i<ca.length; i++) {
                var c = ca[i];
                while (c.charAt(0)==' ') c = c.substring(1);
                if (c.indexOf(name) != -1) return c.substring(name.length, c.length);
            }
            return "";
        }
        //清除cookie  
        function clearCookie(name) {  
            setCookie(name, "", -1);  
        }  
        function checkCookie() {
            var user = getCookie("username");
            if (user != "") {
                alert("Welcome again " + user);
            } else {
                user = prompt("Please enter your name:", "");
                if (user != "" && user != null) {
                    setCookie("username", user, 365);
                }
            }
        }
        checkCookie(); 
        </script>
        第二种方法<script>
        //JS操作cookies方法!
        
        //写cookies
        function setCookie(c_name, value, expiredays){
             var exdate=new Date();
            exdate.setDate(exdate.getDate() + expiredays);
            document.cookie=c_name+ "=" + escape(value) + ((expiredays==null) ? "" : ";expires="+exdate.toGMTString());
           }
         
        //读取cookies
        function getCookie(name)
        {
            var arr,reg=new RegExp("(^| )"+name+"=([^;]*)(;|$)");
         
            if(arr=document.cookie.match(reg))
         
                return (arr[2]);
            else
                return null;
        }
        
        //删除cookies
        function delCookie(name)
        {
            var exp = new Date();
            exp.setTime(exp.getTime() - 1);
            var cval=getCookie(name);
            if(cval!=null)
                document.cookie= name + "="+cval+";expires="+exp.toGMTString();
        }
        //使用示例
        setCookie('username','Darren',30) 
        alert(getCookie("username"));
        </script>
        例子<html> 
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
            <head> 
                <script language="JavaScript" type="text/javascript"> 
                    
                    function addCookie(objName, objValue, objHours){//添加cookie 
                        var str = objName + "=" + escape(objValue); 
                        if (objHours > 0) {//为0时不设定过期时间,浏览器关闭时cookie自动消失 
                            var date = new Date(); 
                            var ms = objHours * 3600 * 1000; 
                            date.setTime(date.getTime() + ms); 
                            str += "; expires=" + date.toGMTString(); 
                        } 
                        document.cookie = str; 
                        alert("添加cookie成功"); 
                    } 
                    
                    function getCookie(objName){//获取指定名称的cookie的值 
                        var arrStr = document.cookie.split("; "); 
                        for (var i = 0; i < arrStr.length; i++) { 
                            var temp = arrStr[i].split("="); 
                            if (temp[0] == objName) 
                                return unescape(temp[1]); 
                        } 
                    } 
                    
                    function delCookie(name){//为了删除指定名称的cookie,可以将其过期时间设定为一个过去的时间 
                        var date = new Date(); 
                        date.setTime(date.getTime() - 10000); 
                        document.cookie = name + "=a; expires=" + date.toGMTString(); 
                    } 
                    
                    function allCookie(){//读取所有保存的cookie字符串 
                        var str = document.cookie; 
                        if (str == "") { 
                            str = "没有保存任何cookie"; 
                        } 
                        alert(str); 
                    } 
                    
                    function $(m, n){ 
                        return document.forms[m].elements[n].value; 
                    } 
                    
                    function add_(){ 
                        var cookie_name = $("myform", "cookie_name"); 
                        var cookie_value = $("myform", "cookie_value"); 
                        var cookie_expireHours = $("myform", "cookie_expiresHours"); 
                        addCookie(cookie_name, cookie_value, cookie_expireHours); 
                    } 
                    
                    function get_(){ 
                        var cookie_name = $("myform", "cookie_name"); 
                        var cookie_value = getCookie(cookie_name); 
                        alert(cookie_value); 
                    } 
                    
                    function del_(){ 
                        var cookie_name = $("myform", "cookie_name"); 
                        delCookie(cookie_name); 
                        alert("删除成功"); 
                    } 
                </script> 
            </head> 
            <body> 
                <form name="myform"> 
                    <div> 
                        <label for="cookie_name"> 
                            名称 
                        </label> 
                        <input type="text" name="cookie_name" /> 
                    </div> 
                    <div> 
                        <label for="cookie_value"></lable> 
                        <input type="text" name="cookie_value" /> 
                    </div> 
                    <div> 
                        <label for="cookie_expireHours"> 
                        多少个小时过期 
                        </lable> 
                        <input type="text" name="cookie_expiresHours" /> 
                    </div> 
                    <div> 
                        <input type="button" value="添加该cookie" onclick="add_()"/><input type="button" value="读取所有cookie" onclick="allCookie()"/><input type="button" value="读取该名称cookie" onclick="get_()"/><input type="button" value="删除该名称cookie" onclick="del_()"/> 
                    </div> 
                </form> 
        </body> 
        </html>

            

    •  报文主体和实体主体的差异
    1. 报文:message
    2. 实体:entity

      通常,报文主体 == 实体主体。只有当传输进行编码时,实体主体内容发生变化,才会导致报文主体产生差异。

    • 压缩传输内容

      HTTP 协议中有一种被称为内容编码的功能也能进行类似的操作。这个编码功能是应用在实体上的,并保持实体原样压缩。编码后的实体由客户端接收并负责解码。

      常用的内容编码有:

    1. gzip(Gnu zip);
    2. compress
    3. deflate(zlib)
    4. identity(不进行编码)

    获取指定范围的请求(断点续传功能),指定范围发送的请求:

    执行范围请求时,会用到首部字段  Range 来指定资源的 byte 范围:如

    从5000 ~ 10000 字节:
    Range:  bytes = 5000 - 10000;
    
    5000以后的全部字节:
    Range:  bytes = 5000 -;
    
    从一开始到3000字节,和5000~7000字节
    Range: bytes = -3000, 5000 - 7000;
    • HTTP 状态码,是http请求返回结果的标记、服务端处理是否正常、通知出现的错误:
    1. 1XX Informational      信息状态码,表示:接收的请求正在处理;
    2. 2XX Success              成功状态码,表示:请求正常处理完毕;
    3. 3XX Redirection         重定向状态码,表示:需要进行附加操作以完成请求;
    4. 4XX Client Error        客户端错误状态码,表示:服务器无法处理请求;
    5. 5XX Server Error      服务器错误状态码,表示:服务器处理请求出错;

    常用状态码:

    2XX   成功   向服务器请求成功;

    1. 204   表示:服务器接收的请求已成功处理,但没有资源返回;
    2. 206   表示:客户端进行了范围请求,服务端已经成功执行了这个请求;
    3. 200   表示:客户端请求成功;

    3XX   重定向    浏览器需要执行某些特殊的处理。当301、302、303响应状态码返回时,几乎所有的浏览器都会把post改成get,并删除报文主体,之后请求会自动发送。

    1. 301    永久性重定向    表示请求的资源巳被重新分配了URI,希望用户能使用新的URI访问
    2. 302    临时重定向       表示请求的URI资源巳临时定位到其它位置了,希望用户能使用新的URI访问
    3. 303    与302有着相同的功能,但303明确表示客户端应采用GET方法
    4. 304    附带条件请求时,它和重定向没有任何关系

    4XX   客户端错误

    1. 400   请求方法错误或请求参数错误
    2. 401   请求需要通过http验证token
    3. 403   请求被服务器拒绝,未获取访问服务器的授权
    4. 404   服务器上无法找到请求的资源

    5XX   服务端错误

    1. 500   服务端错误
    2. 503   服务器暂时处于超负荷状态,无法进行请求
    • 单台虚拟主机实现多个域名
    • 通信数据转发程序:
    1. 代理:有转发功能的应用程序
    2. 网关:它自己没有资源,通过网关提交的请求,这个请求资源是网关从其它服务器转发过来的,它具有转发其它服务器资源的功能
    3. 隧道:相隔很远的服务器与客户端进行中转
    • Cookie
    1. Cookie是管理服务端与客户端之间的状态,它的工作机制是用户识别以及状态管理。
    2. 目前使用最广泛的Cookie标准不是RFC(网景公司)中定义的任何一个。
    3. Cookie的首部字段,说明首部类型 Set-Cookie开始状态管理所使用的Cookie信息响应
    4. Set-Cookie:  键值对的格式
      1.             NAME = VALUE
        Set-Cookie: status = enable; 打开状态 expires = Tue, 05 Jul 2011 07:26:31 GMT; Cookie的有效期 path = /; 服务器上的文件目录 domain = www.baidu.com; 对象的域名,若不指定,则默认为创建Cookie的服务器域名
      2. expires      属性,指浏览器可发送cookie的有效期。一旦 Cookie从服务器端发送至客户端,服务器端就不存在可以显式的删除Cookie的方法。但可以通过覆盖巳过期的Cookie,实现对Cookie实质性的删除。
      3. path          属性,Cookie的path属性可用于限制指定Cookie的发送范围的文件目录。
      4. domain     属性,通过Cookie的domain属性指定域名可做到与结尾匹配一致。因此,不指定具体的域名,也就是不定的domain属性显示得安全。
      5. secure      属性,用于限制WEB页面仅在HTTPS安全链接时,才可以发送cookie。
        1. Set-Cookie: name = value;
              secrue    

          当省略 secrue 属性时,不论HTTP还是HTTPS,都会对Cookie进行回收。
      6. HttpOnly      属性,是Cookie的扩展功能,它使javascript无法获取 Cookie。其目的主要是防止跨站攻击。
        1. Set-Cookie: name = value;
            HttpOnly

          通常从web页面可以读取cookie。如果使用这个属性,在使用javascritp的 document.cookie 就无法读取Cookie了
      7. Cookie: status = enable       这是cookie的首部字段,目的是告知服务器,当客户端想获得HTTP状态管理支持时,就会在请求中包含从服务器接收到的Cookie.
      8. Cookie 最常用的首部字段:
        1. X-Frame-Options    
          X-Frame-Options: DENY
    5.  确保web安全的 https
      1. 使用HTTPS通信机制可以有效地防止这些问题。
      2. HTTP的缺点:
        1. 通信使用明文,不加密,内容可能会被窃听;
        2. 不验证通信方的身份,因此有可能遭到伪装;
        3. 无法证明报文的完整性,有可能巳遭篡改;
      3. HTTP的抓包工具:
        1. Wireshark:它可以获取HTTP协议的请求和响应的内容,并对其进行解析。像查看GET请求,并查看HTTP报文内容都可以做到。
      4. HTTPS 是身披SSL外壳的HTTP
        1. HTTPS并非是应用层的一种新协议,只是HTTP通信接口部分用SSL和TLS协议代替而巳。通常,HTTP直接和TCP通信。当使用SSL时,则演变成先和SSL通信,再由SSL和TCP通信。所以这个HTTPS(SSL),最后的这个S就是指 SSL.
        2. 采用SSL,HTTP就拥有了HTTPS加密、证书和完整性保护。这些功能。
        3. SSL是独立的。除了HTTP,其它应用层,比如SMTP 和 Telnet等协议均可配合 SSL 协议使用。
        4. SSL是当前世界上使用最广泛的网络安全技术。

    这本书,断断续续的看了一个月,了解了一下我比较关注的几个知识点,还需要进一步的加深阅读层次。

  • 相关阅读:
    第一个Servlet项目(IDEA)
    Web交互基本流程以及HTTP协议详解
    mybatis中Mapper.xml配置详解
    认识mybatis
    SpringAOP
    Spring AOP
    70. Climbing Stairs
    位运算
    Leetcode分类
    21. Merge Two Sorted Lists
  • 原文地址:https://www.cnblogs.com/baiyygynui/p/5593191.html
Copyright © 2020-2023  润新知