编程进阶网编程进阶网
  • 基础组成体系
  • 程序编程原理
  • 异常和IO系统
  • 六大设计原则
  • 设计模式导读
  • 创建型设计模式
  • 结构型设计模式
  • 行为型设计模式
  • 设计模式案例
  • 面向对象思想
  • 基础入门
  • 高级进阶
  • JVM虚拟机
  • 数据集合
  • Java面试题
  • C语言入门
  • C综合案例
  • C标准库
  • C语言专栏
  • C++入门
  • C++综合案例
  • C++专栏
  • HTML
  • CSS
  • JavaScript
  • 前端专栏
  • Swift
  • iOS入门
  • 基础入门
  • 开源库解读
  • 性能优化
  • Framework
  • 方案设计
  • 媒体音视频
  • 硬件开发
  • Groovy
  • 常用工具
  • 大厂面试题
  • 综合案例
  • 网络底层
  • Https
  • 网络请求
  • 故障排查
  • 专栏
  • 数组
  • 链表
  • 栈
  • 队列
  • 树
  • 递归
  • 哈希
  • 排序
  • 查找
  • 字符串
  • 其他
  • Bash脚本
  • Linux入门
  • 嵌入式开发
  • 代码规范
  • Markdown
  • 开发理论
  • 开发工具
  • Git管理
  • 百宝箱
  • 开源协议
  • 技术招聘
  • 测试经验
  • 职场提升
  • 技术模版
  • 关于我
  • 目标清单
  • 学习框架
  • 育儿经验
  • 我的专栏
  • 底层能力
  • 读书心得
  • 随笔笔记
  • 职场思考
  • 中华历史
  • 经济学故事
  • 基础组成体系
  • 程序编程原理
  • 异常和IO系统
  • 六大设计原则
  • 设计模式导读
  • 创建型设计模式
  • 结构型设计模式
  • 行为型设计模式
  • 设计模式案例
  • 面向对象思想
  • 基础入门
  • 高级进阶
  • JVM虚拟机
  • 数据集合
  • Java面试题
  • C语言入门
  • C综合案例
  • C标准库
  • C语言专栏
  • C++入门
  • C++综合案例
  • C++专栏
  • HTML
  • CSS
  • JavaScript
  • 前端专栏
  • Swift
  • iOS入门
  • 基础入门
  • 开源库解读
  • 性能优化
  • Framework
  • 方案设计
  • 媒体音视频
  • 硬件开发
  • Groovy
  • 常用工具
  • 大厂面试题
  • 综合案例
  • 网络底层
  • Https
  • 网络请求
  • 故障排查
  • 专栏
  • 数组
  • 链表
  • 栈
  • 队列
  • 树
  • 递归
  • 哈希
  • 排序
  • 查找
  • 字符串
  • 其他
  • Bash脚本
  • Linux入门
  • 嵌入式开发
  • 代码规范
  • Markdown
  • 开发理论
  • 开发工具
  • Git管理
  • 百宝箱
  • 开源协议
  • 技术招聘
  • 测试经验
  • 职场提升
  • 技术模版
  • 关于我
  • 目标清单
  • 学习框架
  • 育儿经验
  • 我的专栏
  • 底层能力
  • 读书心得
  • 随笔笔记
  • 职场思考
  • 中华历史
  • 经济学故事
  • 4.1请求网络过程分析
  • 4.2网络请求流程的详解
  • 4.3Curl实践技巧用法
  • 4.7Cookie,Session和Token

4.2网络请求流程的详解

目录介绍

  • 01.Http请求与响应
    • 1.1 HTTP请求包的结构
    • 1.2 HTTP响应包结构
    • 1.3 通用头部和报文描述
    • 1.4 浏览器接口请求头和响应头
  • 02.重要专业名次说明
    • 2.2 常见Content-Type定义
  • 03.普通get和post网络请求
    • 3.1 GET请求场景
    • 3.2 POST请求场景
    • 3.3 GET和POST区别
    • 3.4 GET请求代码
    • 3.5 POST请求代码
    • 3.6 浏览器对url限制
    • 3.7 请求的安全性
    • 3.8 其他网络请求方式
  • 04.Http响应方式
  • 05.请求链接URI和URL
    • 5.1 看一个案例
    • 5.2 uri详细介绍
    • 5.3 URL详细介绍
    • 5.4 URI何URL联系
  • 06.Http缓存机制讲解
    • 6.1 request请求字段含义
    • 6.2 response响应字段含义
    • 6.3 缓存机制逻辑图

01.Http请求与响应

  • 一次请求
    • 就是向目标服务器发送一串文本。什么样的文本?有下面结构的文本。
  • 什么是Http报文
    • 它是HTTP应用程序之间发送的数据块。这些数据块以一些文本形式的元信息开头,这些信息描述了报文的内容及含义,后面跟着可选的数据部分。这些报文都是在客户端、服务器和代理之间流动。
    • HTTP报文是面向文本的,报文中的每一个字段都是一些ASCII码串,各个字段的长度是不确定的。
    • HTTP有两类报文:请求报文(客户端)和响应报文(服务端)。
  • HTTP报文的流动方向
    • 一次HTTP请求,HTTP报文会从“客户端”流到“代理”再流到“服务器”,在服务器工作完成之后,报文又会从“服务器”流到“代理”再流到“客户端”。

1.1 HTTP请求包的结构

1.1.1 请求报文
  • 请求报文动作:
    • 它会向Web服务器请求一个动作
  • 请求报文结构格式:
    请求行: <method> <request-URL> <version>
    头部:   <headers>
    主体:   <entity-body>
  • 请求报文结构示意图:
    • image
      image
  • 例子:
    • 请求了就会收到响应包(如果对面存在HTTP服务器)
    POST /meme.php/home/user/login HTTP/1.1
    Host: 114.215.86.90
    Cache-Control: no-cache
    Postman-Token: bd243d6b-da03-902f-0a2c-8e9377f6f6ed
    Content-Type: application/x-www-form-urlencoded
    
    tel=13637829200&password=123456
1.1.2 请求行
  • 请求行
    • 什么是请求行:
      • 所有的HTTP请求报文都以一个请求行作为开始。请求报文的起始行说明了要做些什么。
    • 请求报文的请求行:
      • 该行包含了一个方法和一个请求的URL,还包含HTTP 的版本。
1.1.3 请求头
  • 请求头
    • 请求头部:请求头部是只在请求报文中有意义的头部。用于说明是谁或什么在发送请求、请求源自何处,或者客户端的喜好及能力。
  • 请求头部有哪些?
    Client-IP:提供了运行客户端的机器的IP地址
    From:提供了客户端用户的E-mail地址
    Host:给出了接收请求的服务器的主机名和端口号
    Referer:提供了包含当前请求URI的文档的URL
    UA-Color:提供了与客户端显示器的显示颜色有关的信息
    UA-CPU:给出了客户端CPU的类型或制造商
    UA-OS:给出了运行在客户端机器上的操作系统名称及版本
    UA-Pixels:提供了客户端显示器的像素信息
    User-Agent:将发起请求的应用程序名称告知服务器       
    Accept:告诉服务器能够发送哪些媒体类型
    Accept-Charset:告诉服务器能够发送哪些字符集
    Accept-Encoding:告诉服务器能够发送哪些编码方式
    Accept-Language:告诉服务器能够发送哪些语言
    TE:告诉服务器可以使用那些扩展传输编码
    Expect:允许客户端列出某请求所要求的服务器行为
    Range:如果服务器支持范围请求,就请求资源的指定范围
    If-Match:如果实体标记与文档当前的实体标记相匹配,就获取这份文档
    If-Modified-Sinec:除非在某个指定的日期之后资源被修改过,否则就限制这个请求
    If-None-Match:如果提供的实体标记与当前文档的实体标记不相符,就获取文档
    If-Range:允许对文档的某个范围进行条件请求
    If-Unmodified-Since:除非在某个指定日期之后资源没有被修改过,否则就限制这个请求
    Authorization:包含了客户端提供给服务器,以便对其自身进行认证的数据
    Cookie:客户端用它向服务器传送数据
    Cookie2:用来说明请求端支持的cookie版本
    Max-Forward:在通往源端服务器的路径上,将请求转发给其他代理或网关的最大次数
    Proxy-Authorization:这个首部在与代理进行认证时使用的
    Proxy-Connection:这个首部是在与代理建立连接时使用的
  • 常见的是那些
    • User-Agent:产生请求的浏览器类型。
    • Accept:客户端可识别的响应内容类型列表;
    • Accept-Language:客户端可接受的自然语言;
    • Accept-Encoding:客户端可接受的编码压缩格式;
    • Host:请求的主机名,允许多个域名同处一个IP 地址,即虚拟主机;
    • Connection:连接方式(close 或 keep-alive);
    • Cookie:存储于客户端扩展字段,向同一域名的服务端发送属于该域的cookie;

1.2 HTTP响应包结构

1.2.1 响应报文
  • 响应报文动作:
    • 它会将请求的结果返回给客户端。
  • 响应报文结构格式:
    状态行:  <version> <status> <reason-phrase>
    响应头部:    <headers>
    响应主体:    <entity-body>
  • 响应报文结构示意图:
    • image
      image
  • 例子:
    HTTP/1.1 200 OK
    Date: Sat, 02 Jan 2016 13:20:55 GMT
    Server: Apache/2.4.6 (CentOS) PHP/5.6.14
    X-Powered-By: PHP/5.6.14
    Content-Length: 78
    Keep-Alive: timeout=5, max=100    Connection: Keep-Alive
    Content-Type: application/json; charset=utf-8
    
    {"status":202,"info":"\u6b64\u7528\u6237\u4e0d\u5b58\u5728\uff01","data":null}
1.2.2 状态行
  • 什么是状态行:
    • 所有的HTTP响应报文都以一个状态行作为开始。响应报文的起始行说明发生了什么。
  • 响应报文的状态行:
    • 该行包含了响应报文使用的HTTP版本、数字状态码、原因短语。
1.2.3 响应头
  • 响应头部:
    • 响应头部为客户端提供了一些额外信息,比如谁在发送响应、响应者的功能,甚至与响应相关的一些特殊指令
  • 响应头部有哪些?
    Age:(从最初创建开始)响应持续时间
    Public:服务器为其资源支持的请求方法列表
    Retry-After:如果资源不可用的话,在此日期或时间重试
    Server:服务器应用程序软件的名称和版本
    Title:对HTML文档来说,就是HTML文档的源端给出的标题
    Warning:比原因短语更详细一些的警告报文
    Accept-Ranges:对此资源来说,服务器可接受的范围类型
    Vary:服务器会根据这些首部的内容挑选出最适合的资源版本发送给客户端
    Proxy-Authenticate:来自代理的对客户端的质询列表
    Set-Cookie:在客户端设置数据,以便服务器对客户端进行标识
    Set-Cookie2:与Set-Cookie类似
    WWW-Authenticate:来自服务器的对客户端的质询列表
  • 常见的响应头部参数
    • Allow 服务器支持哪些请求方法(如GET、POST等)。
    • Content-Encoding 文档的编码(Encode)方法。
    • Content-Length 表示内容长度。只有当浏览器使用持久HTTP连接时才需要这个数据。
    • Content-Type 表示后面的文档属于什么MIME类型。
    • Server 服务器名字。
    • Set-Cookie 设置和页面关联的Cookie。
    • ETag:被请求变量的实体值。ETag是一个可以与Web资源关联的记号(MD5值)。
    • Cache-Control:这个字段用于指定所有缓存机制在整个请求/响应链中必须服从的指令。

1.3 通用头部和报文描述

  • 通用头部:
    • 既可以出现在请求报文中,也可以出现在响应报文中,它提供了与报文相关的最基本的信息
  • 通用头部有哪些?
    • Connection:允许客户端和服务器指定与请求/响应连接有关的选项
    • Date:提供日期和时间标志,说明报文是什么时间创建的
    • MIME-Version:给出了发送端使用的MIME版本
    • Trailer:如果报文采用了分块传输编码方式,就可以用这个首部列出位于报文拖挂部分的首部集合
    • Transfer-Encoding:告知接收端为了保证报文的可靠传输,对报文采用了什么编码方式
    • Update:给出了发送端可能想要“升级”使用的新版本或协议
    • Via:显示了报文经过的中间节点(代理、网关)
    • Cache-Control:用于随报文传送缓存指示
  • 报文各部分的描述
    • 1、方式(method):客户端希望服务器对资源执行的动作,是一个单独的词,比如,GET、POST或HEAD
    • 2、请求URL(request-URL):要直接与服务器进行对话,只要请求URL是资源的绝对路径就可以了,服务器可以假定自己是URL的主机/端口
    • 3、版本(version):报文所使用的HTTP版本。其格式:HTTP/<主要版本号>.<次要版本号>
    • 4、状态码(status-code):状态码是三位数字,描述了请求过程中所发生的情况。每个状态码的第一位数字都用于描述状态的一般类别(比如,“成功”、“出错”等等)
    • 5、原因短语(reason-phrase):数字状态码的可读版本,包含行终止序列之前的所有文本。原因短语只对人类有意义,因此,尽管响应行HTTP/1.0 200 NOT OK和HTTP/1.0 200 OK中原因短语的含义不同,但同样都会被当作成功指示处理
    • 6、头部(header):可以有零个或多个头部,每个首部都包含一个名字,后面跟着一个冒号(😃,然后是一个可选的空格,接着是一个值,最后是一个CRLF首部是由一个空行(CRLF)结束的,表示了头部列表的结束和实体主体部分的开始
    • 7、实体的主体部分(entity-body):实体的主体部分包含一个由任意数据组成的数据块,并不是所有的报文都包含实体的主体部分,有时,报文只是以一个CRLF结束。

1.4 浏览器接口请求头和响应头

  • 请求接口如下所示
    • https://www.wanandroid.com/friend/json
  • General
    • Request URL: https://www.wanandroid.com/friend/json
    • Request Method: GET
    • Status Code: 200 OK
    • Remote Address: 47.104.74.169:443
    • Referrer Policy: no-referrer-when-downgrade
  • Response Header
    • HTTP/1.1 200 OK
    • Server: Apache-Coyote/1.1
    • Cache-Control: private
    • Expires: Thu, 01 Jan 1970 08:00:00 CST
    • Content-Type: application/json;charset=UTF-8
    • Transfer-Encoding: chunked
    • Date: Thu, 10 Sep 2020 01:05:47 GMT
  • Request Header
    • Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.9
    • Accept-Encoding: gzip, deflate, br
    • Accept-Language: zh-CN,zh;q=0.9
    • Cache-Control: no-cache
    • Connection: keep-alive
    • Cookie: JSESSIONID=5D6302E64E9734210FA231A6FAF5799E; Hm_lvt_90501e13a75bb5eb3d067166e8d2cad8=1598920692,1599007288,1599094016,1599629553; Hm_lpvt_90501e13a75bb5eb3d067166e8d2cad8=1599699419
    • Host: www.wanandroid.com
    • Pragma: no-cache
    • Sec-Fetch-Dest: document
    • Sec-Fetch-Mode: navigate
    • Sec-Fetch-Site: none
    • Upgrade-Insecure-Requests: 1
    • User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36
  • Response返回body
    • 这里省略
  • 看截图如下
    • image
      image

02.重要专业名次说明

2.2 常见Content-Type定义

  • 普通文本:text/plain
  • 表单键值对:application/x-www-form-urlencoded
  • 文件和字符数据一起传递的多块数据:multipart/form-data
  • 文件数据:application/octet-stream
  • json数据:application/json
  • xml数据:text/xml

03.普通get和post网络请求

3.1 GET请求场景

  • 在url中填写参数
    http://xxxx.xx.com/xx.php?params1=value1&params2=value2
    https://api.douban.com/v2/book/search?tag=文学&start=0&count=30
  • 有关 GET 请求的其他一些注释:
    • GET 请求可被缓存
    • GET 请求保留在浏览器历史记录中
    • GET 请求可被收藏为书签
    • GET 请求不应在处理敏感数据时使用
    • GET 请求有长度限制
    • GET 请求只应当用于取回数据

3.2 POST请求场景

  • 请注意,查询字符串(名称/值对)是在 POST 请求的 HTTP 消息主体中发送的:
    POST /test/demo_form.asp HTTP/1.1
    Host: taobao.com
    name1=value1&name2=value2
  • 有关 POST 请求的其他一些注释:
    • POST 请求不会被缓存
    • POST 请求不会保留在浏览器历史记录中
    • POST 不能被收藏为书签
    • POST 请求对数据长度没有要求

3.3 GET和POST区别

  • GET和POST区别
    • Get请求的参数是直接放在url后面的,而Post请求是放在请求体中的
    • Get请求参数拼接的url的长度会根据浏览器的不同实现有一定限制,而Post请求参数长度没有限制
    • Get请求方便测试,直接输入地址即可,而Post请求不方便测试,需要借助代码或者工具进行发送
  • 注意误解:
    • Get传递数据上限XXX;胡说。有限制的是浏览器中的url长度,不是Http协议,移动端请求无影响。Http服务器部分有限制的设置一下即可。
    • HTTP的底层是TCP/IP。所以GET和POST的底层也是TCP/IP,也就是说,GET/POST都是TCP链接。GET和POST能做的事情是一样一样的。
  • GET产生一个TCP数据包;POST产生两个TCP数据包。
    • 对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
    • 而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。
    • POST需要两步,时间上消耗一定要多一点吗?看起来GET比POST更有效吗?答案是不一定的。
      • GET与POST都有自己的语义,不能随便混用。
      • 据研究,在网络环境好的情况下,发一次包的时间和发两次包的时间差别基本可以无视。而在网络环境差的情况下,两次包的TCP在验证数据包完整性上,有非常大的优点。
      • 并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次。
  • 登陆或者购物添加商品使用get还是post?
    • 使用post请求,因为针对这种涉及隐私的请求,应该将请求参数防到请求体中,避免被窃取。
  • 关于GET和POST其他区别关系图【参考:w3schools】
    • image
      image

3.4 GET请求代码

  • 代码如下所示
    public static String get(String url) {
        HttpURLConnection conn = null;
        try {
            // 利用string url构建URL对象
            URL mURL = new URL(url);
            // 调用URL的openConnection()方法,获取HttpURLConnection对象
            conn = (HttpURLConnection) mURL.openConnection();
            // 设置请求方法为get
            conn.setRequestMethod("GET");
            // 设置读取超时为5秒
            conn.setReadTimeout(5000);
            // 设置连接网络超时为10秒
            conn.setConnectTimeout(10000);
            // 调用此方法就不必再使用conn.connect()方法
            int responseCode = conn.getResponseCode();
            if (responseCode == 200) {
                //返回从打开的连接读取的输入流
                InputStream is = conn.getInputStream();
                String response = getStringFromInputStream(is);
                return response;
            } else {
                throw new NetworkErrorException("response status is "+responseCode);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
    
            if (conn != null) {
                conn.disconnect();
            }
        }
        return null;
    }
    
    private static String getStringFromInputStream(InputStream is) throws IOException {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        // 模板代码 必须熟练
        byte[] buffer = new byte[1024];
        int len = -1;
        while ((len = is.read(buffer)) != -1) {
            os.write(buffer, 0, len);
        }
        is.close();
        // 把流中的数据转换成字符串,采用的编码是utf-8(模拟器默认编码)
        String state = os.toString();
        os.close();
        return state;
    }

3.5 POSt请求代码

  • 代码如下所示
    public static String post(String url, String content) {
        HttpURLConnection conn = null;
        try {
            // 创建一个URL对象
            URL mURL = new URL(url);
            // 调用URL的openConnection()方法,获取HttpURLConnection对象
            conn = (HttpURLConnection) mURL.openConnection();
            // 设置请求方法为post
            conn.setRequestMethod("POST");
            // 设置读取超时为5秒
            conn.setReadTimeout(5000);
            // 设置连接网络超时为10秒
            conn.setConnectTimeout(10000);
            // 设置此方法,允许向服务器输出内容
            conn.setDoOutput(true);
    
            // post请求的参数
            String data = content;
            // 获得一个输出流,向服务器写数据,默认情况下,系统不允许向服务器输出内容
            // 获得一个输出流,向服务器写数据
            OutputStream out = conn.getOutputStream();
            out.write(data.getBytes());
            out.flush();
            out.close();
    
            // 调用此方法就不必再使用conn.connect()方法
            int responseCode = conn.getResponseCode();
            if (responseCode == 200) {
                InputStream is = conn.getInputStream();
                String response = getStringFromInputStream(is);
                return response;
            } else {
                throw new NetworkErrorException("response status is "+responseCode);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (conn != null) {
                conn.disconnect();// 关闭连接
            }
        }
        return null;
    }
    
    
    private static String getStringFromInputStream(InputStream is) throws IOException {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        // 模板代码 必须熟练
        byte[] buffer = new byte[1024];
        int len = -1;
        while ((len = is.read(buffer)) != -1) {
            os.write(buffer, 0, len);
        }
        is.close();
        // 把流中的数据转换成字符串,采用的编码是utf-8(模拟器默认编码)
        String state = os.toString();
        os.close();
        return state;
    }

3.6 浏览器对url限制

  • 注意这句话是错的:
    • Get传递数据上限XXX;胡说。有限制的是浏览器中的url长度,不是Http协议,移动端请求无影响。Http服务器部分有限制的设置一下即可。
  • 业界不成文的规定是
    • 大多数浏览器通常都会限制url长度在2K个字节,而(大多数)服务器最多处理64K大小的url。超过的部分,恕不处理。如果你用GET服务,不同服务器的处理方式也是不同的,有些服务器会帮你卸货,读出数据,有些服务器直接忽略,所以,虽然GET可以带request body,也不能保证一定能被接收到哦。

3.7 请求的安全性

  • POST的安全性要比GET的安全性高。注意:这里所说的安全性和上面GET提到的“安全”不是同个概念。
  • 上面“安全”的含义仅仅是不作数据修改,而这里安全的含义是真正的Security的含义,比如:通过GET提交数据,用户名和密码将明文出现在URL上,因为(1)登录页面有可能被浏览器缓存,(2)其他人查看浏览器的历史纪录,那么别人就可以拿到你的账号和密码。

3.8 其他网络请求方式

  • 常见的请求网络方式
    • Image.png
      Image.png
  • GET获取资源
    • 当前网络请求中,绝大部分使用的是 GET 方法。
  • POST传输实体主体
    • 传输实体主体
    • POST 主要用来传输数据,而 GET 主要用来获取资源。
  • PUT传输文件
    • 上传文件
    • 由于自身不带验证机制,任何人都可以上传文件,因此存在安全性问题,一般不使用该方法。
    PUT /new.html HTTP/1.1
    Host: example.com
    Content-type: text/html
    Content-length: 16
    
    <p>New File</p>
  • HEAD获取报文首部
    • 获取报文首部
    • 和 GET方法一样,但是不返回报文实体主体部分。
    • 主要用于确认URL的有效性以及资源更新的日期时间等。
  • DELETE删除文件
    • 删除文件
    • 与 PUT 功能相反,并且同样不带验证机制。
    DELETE /file.html HTTP/1.1
  • TRACE追踪路径
    • 追踪路径
    • 服务器会将通信路径返回给客户端。
    • 发送请求时,在 Max-Forwards 首部字段中填入数值,每经过一个服务器就会减 1,当数值为 0 时就停止传输。
    • 通常不会使用 TRACE,并且它容易受到 XST 攻击(Cross-Site Tracing,跨站追踪)。
  • OPTIONS对资源进行部分修改
    • 查询支持的方法
    • 查询指定的 URL 能够支持的方法。
    • 会返回 Allow: GET, POST, HEAD, OPTIONS 这样的内容。
  • CONNECT与代理服务器通信时建立隧道
    • 要求在与代理服务器通信时建立隧道
    • 使用 SSL(Secure Sockets Layer,安全套接层)和 TLS(Transport Layer Security,传输层安全)协议把通信内容加密后经网络隧道传输。
    CONNECT www.example.com:443 HTTP/1.1
  • PATCH对资源进行部分修改
    • 对资源进行部分修改
    • PUT 也可以用于修改资源,但是只能完全替代原始资源,PATCH 允许部分修改。
    PATCH /file.txt HTTP/1.1
    Host: www.example.com
    Content-Type: application/example
    If-Match: "e0023aa4e"
    Content-Length: 100
    
    [description of changes]

04.Http响应方式

  • 请求是键值对,但返回数据我们常用Json。
  • 对于内存中的结构数据,肯定要用数据描述语言将对象序列化成文本,再用Http传递,接收端并从文本还原成结构数据。
  • 对象(服务器)<-->文本(Http传输)<-->对象(移动端) 。

05.请求链接URI和URL

5.1 看一个案例

  • 看看下面的链接,说一下哪些是uri,哪些是url
    • https://github.com/yangchong211/LifeHelper 这个是url
    • http://localhost:8080/index.html 这个是url
    • http://xxxx.xx.com/xx.php?params1=value1&params2=value2 这个是url

5.2 uri详细介绍

  • 什么是uri
    • URI全称是Uniform Resource Identifier,也就是统一资源标识符,它是一种采用特定的语法标识一个资源的字符串表示。
    • URI所标识的资源可能是服务器上的一个文件,也可能是一个邮件地址、图书、主机名等。简单记为:URI是标识一个资源的字符串(这里先不必纠结标识的目标资源到底是什么,因为使用者一般不会见到资源的实体),从服务器接收到的只是资源的一种字节表示(二进制序列,从网络流中读取)。
  • 通用URI的格式如下:
    • scheme:[//[user[:password]@]host[:port]][/path][?query][#fragment]
  • 如下所示
    • image
      image
  • 举个例子
    //打开这个地址,发现竟然是github.com/yangchong211
    http://site1.com@www.github.com/yangchong211
  • URI一般由三部组成
    • ①访问资源的命名机制
    • ②存放资源的主机名
    • ③资源自身的名称,由路径表示,着重强调于资源。
  • URI当前的常用模式包括:
    • data:链接中直接包含经过BASE64编码的数据。
    • file:本地磁盘上的文件。
    • ftp:FTP服务器。
    • http:使用超文本传输协议。
    • mailto:电子邮件的地址。
    • magnet:可以通过对等网络(端对端P2P,如BitTorrent)下载的资源。
    • telnet:基于Telnet的服务的连接。
    • urn:统一资源名(Uniform Resource Name)。
  • URI (Uniform Resource Identifier,统一资源标识符)。
    • URI 属于 URL 更高层次的抽象,一种字符串文本标准。就是说,URI 属于父类,而 URL 属于 URI 的子类。URL 是 URI 的一个子集。
    ftp://ftp.is.co.za/rfc/rfc1808.txt (URL)
    http://www.ietf.org/rfc/rfc2396.txt (URL)
    ldap://[2001:db8::7]/c=GB?objectClass?one (URL)
    mailto:John.Doe@example.com (URL)
    news:comp.infosystems.www.servers.unix (URL)
    tel:+1-816-555-1212
    telnet://192.0.2.16:80/ (URL)
    urn:oasis:names:specification:docbook:dtd:xml:4.1.2

5.3 URL详细介绍

  • 什么是url
    • URL全称是Uniform Resource Location,也就是统一资源位置。实际上,URL就是一种特殊的URI,它除了标识一个资源,还会为资源提供一个特定的网络位置,客户端可以通过它来获取URL对应的资源。
    • URL所表示的网络资源位置通常包括用于访问服务器的协议(如http、ftp等)、服务器的主机名或者IP地址、以及资源文件在该服务器上的路径。
    • 典型的URL例如:http://localhost/myProject/index.html,它指示本地服务器的myProject目录下有一个名为index.html的文档,这个文档可以通过http协议访问(实际上,URL不一定是指服务器中的真实的物理路径,因为我们一般在服务器中部署应用,如Servlet应用,URL访问的很可能是应用的接口,至于最终映射到什么资源可以由应用自身决定)。
  • URL(Uniform Resource Locator,统一资源定位符)的格式
    • 通常而言,我们所熟悉的 URL 的常见定义格式为:
      scheme://host[:port#]/path/.../[;url-params][?query-string][#anchor]
      > scheme //有我们很熟悉的http、https、ftp以及著名的ed2k,迅雷的thunder等。
      > host   //HTTP服务器的IP地址或者域名
      > port#  //HTTP服务器的默认端口是80,这种情况下端口号可以省略。如果使用了别的端口,必须指明,例如tomcat的默认端口是8080 http://localhost:8080/
      > path   //访问资源的路径
      > url-params  //所带参数 
      > query-string    //发送给http服务器的数据
      > anchor //锚点定位
  • 格式属性介绍
    • protocol:URL中的协议(protocol)是相应于URI中的模式(schema)的另一个叫法。URL中,协议部分可以是file、ftp、http、https、magnet、telnet或者其他定制协议字符串(但是不包括urn)。
    • userInfo:URL中的用户信息(userInfo)是服务器的登录信息,这部分信息是可选的。如果这部分信息存在,一般会包含一个用户名,极少情况下会包含一个口令。实际上URL携带用户信息是不安全的。
    • port:URL中的端口号(port)是指服务器中应用的运行端口,默认端口为80,此部分信息是可选的(也就如果不指定端口号就使用默认端口80)。
    • path:URL中的路径(path)用于表示服务器上的一个特定的目录(其实说一个特定的文件也可以),这个特定的目录不一定是物理目录,也有可能是逻辑目录。这一点很容易说明,一般不可能把服务器上面的目录直接公开让所有人访问,服务器上面跑的一般是Web(Java的话一般是Servlet)应用,路径指向的实际数据来源甚至很大可能是在其他服务器上的MySQL中的查询结果。
    • query:查询参数(query)一般是一个字符串,它表示URL中向服务器提供的附加参数,一般只使用在http协议的URL中,其中包含了表单数据,来源于用户的输入,表示形式是key1=value1&key2=value2&keyn=valuen。
    • fragment:片段(fragment)表示远程服务器资源的某个特定的部分。假如服务器资源是一个HTML文档,此片段标识符将制定为该HTML文档的一个锚(Anchor)。如果远程资源是一个XML文档,那么这个片段标识符是一个XPointer。
  • URL一般由三部组成
    • ①协议(或称为服务方式)
    • ②存有该资源的主机IP地址(有时也包括端口号)
    • ③主机资源的具体地址。如目录和文件名等。
  • 拼接url链接字符串工具类
    • 比如:https://github.com/yangchong211/LifeHelper?name=yc&age=26
    • 如下所示
    /**
     * 拼接字符串
     * @param url                       url
     * @param map                       map集合
     * @return
     */
    public static String getUrl(String url, HashMap<String, String> map){
        if(TextUtils.isEmpty(url)){
            return null;
        }
        //解析一个url
        Uri uri = Uri.parse(url);
        Uri.Builder builder = uri.buildUpon();
        if (map != null && map.size() > 0) {
            //使用迭代器进行遍历
            for (Object o : map.entrySet()) {
                Map.Entry entry = (Map.Entry) o;
                String key = (String) entry.getKey();
                String value = (String) entry.getValue();
                //对键和值进行编码,然后将参数追加到查询字符串中。
                builder.appendQueryParameter(key, value);
            }
        }
        return builder.toString();
    }
  • URL类中提供对应的方法分别是:
    //解析一个url
    Uri uri = Uri.parse(url);
    // 完整的url信息
    String urlStr = uri.toString();
    Log.e( "UrlUtils","url: " + urlStr);
    // scheme部分
    String scheme = uri.getScheme();
    Log.e( "UrlUtils","scheme: " + scheme);
    // host部分
    String host = uri.getHost();
    Log.e( "UrlUtils","host: " + host);
    //port部分
    int port = uri.getPort();
    Log.e( "UrlUtils","port: " + port);
    // 访问路劲
    String path = uri.getPath();
    Log.e( "UrlUtils","path: " + path);
    List<String> pathSegments = uri.getPathSegments();
    Log.e( "UrlUtils","pathSegments: " + pathSegments.toString());
    // Query部分
    String query = uri.getQuery();
    Log.e( "UrlUtils","query: " + query);
    //获取此URI的解码权限部分。对于服务器地址,权限的结构如下:Examples: "google.com", "bob@google.com:80"
    String authority = uri.getAuthority();
    Log.e( "UrlUtils","authority: " + authority);
    //从权限获取已解码的用户信息。例如,如果权限为“任何人@google.com”,此方法将返回“任何人”。
    String userInfo = uri.getUserInfo();
    Log.e( "UrlUtils","userInfo: " + userInfo);
    
    
    //UrlUtils: url: https://m.dev.haowumc.com/app/financialManagement
    //UrlUtils: scheme: https
    //UrlUtils: host: m.dev.haowumc.com
    //UrlUtils: port: -1
    //UrlUtils: path: /app/financialManagement
    //UrlUtils: pathSegments: [app, financialManagement]
    //UrlUtils: query: null
    //UrlUtils: authority: m.dev.haowumc.com
    //UrlUtils: userInfo: null

5.4 URI何URL联系

  • URI和URL的关系:
    • URL是一种特殊的URI,是URI包括URL。
    • URI属于URL更高层次的抽象,一种字符串文本标准。就是说,URI属于父类,而URL属于URI的子类。URL是URI的一个子集。URI还有一个子类URN-统一资源名称。
  • 二者的区别在于
    • URI 表示请求服务器的路径,定义这么一个资源。
    • URL 同时说明要如何访问这个资源(http://)。

6.Http缓存机制讲解

  • 缓存对于移动端是非常重要的存在。
    • 减少请求次数,减小服务器压力.
    • 本地数据读取速度更快,让页面不会空白几百毫秒。
    • 在无网络的情况下提供数据。
    • 缓存一般由服务器控制(通过某些方式可以本地控制缓存,比如向过滤器添加缓存控制信息)。通过在请求头添加下面几个字端:

6.1 request请求字段含义

  • 如下所示:
    Header            解释    示例
    Accept                  Accept: text/plain, text/html            指定客户端能够接收的内容类型
    Accept-Charset          Accept-Charset: iso-8859-5                浏览器可以接受的字符编码集。
    Accept-Encoding     Accept-Encoding: compress, gzip            指定浏览器可以支持的web服务器返回内容压缩编码类型。
    Accept-Language     Accept-Language: en,zh                    浏览器可接受的语言     
    Accept-Ranges          Accept-Ranges: bytes                    可以请求网页实体的一个或者多个子范围字段
    Authorization          Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==        HTTP授权的授权证书
    Cache-Control          Cache-Control: no-cache                    指定请求和响应遵循的缓存机制
    Connection              Connection: close                        表示是否需要持久连接。(HTTP 1.1默认进行持久连接)
    Cookie              Cookie: $Version=1; Skin=new;            HTTP请求发送时,会把保存在该请求域名下的所有cookie值一起发送给web服务器。
    Content-Length          Content-Length: 348                        请求的内容长度
    Content-Type          Content-Type: application/x-www-form-urlencoded            请求的与实体对应的MIME信息
    Date                  Date: Tue, 15 Nov 2010 08:12:31 GMT        请求发送的日期和时间
    Expect                  Expect: 100-continue                    请求的特定的服务器行为
    From                  From: user@email.com                    发出请求的用户的Email
    Host                  Host: www.zcmhi.com                        指定请求的服务器的域名和端口号
    If-Match              If-Match: "737060cd8c284d8af7ad3082f209582d"            只有请求内容与实体相匹配才有效
    If-Modified-Since     If-Modified-Since: Sat, 29 Oct 2010 19:43:31 GMT        如果请求的部分在指定时间之后被修改则请求成功,未被修改则返回304代码
    If-None-Match          If-None-Match: "737060cd8c284d8af7ad3082f209582d"        如果内容未改变返回304代码,参数为服务器先前发送的Etag,与服务器回应的Etag比较判断是否改变
    If-Range              If-Range: "737060cd8c284d8af7ad3082f209582d"            如果实体未改变,服务器发送客户端丢失的部分,否则发送整个实体。参数也为Etag
    If-Unmodified-Since    If-Unmodified-Since: Sat, 29 Oct 2010 19:43:31 GMT        只在实体在指定时间之后未被修改才请求成功
    Max-Forwards          Max-Forwards: 10                        限制信息通过代理和网关传送的时间
    Pragma                  Pragma: no-cache                        用来包含实现特定的指令
    Proxy-Authorization Proxy-Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==    连接到代理的授权证书
    Range                  Range: bytes=500-999                    只请求实体的一部分,指定范围
    Referer              Referer: http://blog.csdn.net/coder_pig    先前网页的地址,当前请求网页紧随其后,即来路
    TE                      TE: trailers,deflate;q=0.5                客户端愿意接受的传输编码,并通知服务器接受接受尾加头信息
    Upgrade              Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11            向服务器指定某种传输协议以便服务器进行转换(如果支持)
    User-Agent              User-Agent: Mozilla/5.0 (Linux; X11)                    User-Agent的内容包含发出请求的用户信息
    Via                  Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1)                通知中间网关或代理服务器地址,通信协议
    Warning              Warn: 199 Miscellaneous warning                            关于消息实体的警告信息
    • Image.png
      Image.png

6.2 response响应字段含义

  • 如下所示:
    Header    解释    示例
    Accept-Ranges    Accept-Ranges: bytes        表明服务器是否支持指定范围请求及哪种类型的分段请求     
    Age              Age: 12                        从原始服务器到代理缓存形成的估算时间(以秒计,非负)
    Allow              Allow: GET, HEAD            对某网络资源的有效的请求行为,不允许则返回405
    Cache-Control      Cache-Control: no-cache        告诉所有的缓存机制是否可以缓存及哪种类型
    Content-Encoding     Content-Encoding: gzip        web服务器支持的返回内容压缩编码类型
    Content-Language     Content-Language: en,zh        响应体的语言     
    Content-Length         Content-Length: 348            响应体的长度
    Content-Location     Content-Location: /index.htm        请求资源可替代的备用的另一地址
    Content-MD5          Content-MD5: Q2hlY2sgSW50ZWdyaXR5IQ==        返回资源的MD5校验值
    Content-Range          Content-Range: bytes 21010-47021/47022        在整个返回体中本部分的字节位置
    Content-Type          Content-Type: text/html; charset=utf-8        返回内容的MIME类型
    Date                  Date: Tue, 15 Nov 2010 08:12:31 GMT            原始服务器消息发出的时间
    ETag                  ETag: "737060cd8c284d8af7ad3082f209582d"    请求变量的实体标签的当前值
    Expires              Expires: Thu, 01 Dec 2010 16:00:00 GMT        响应过期的日期和时间
    Last-Modified          Last-Modified: Tue, 15 Nov 2010 12:45:26 GMT    请求资源的最后修改时间
    Location              Location: http://blog.csdn.net/coder_pig    用来重定向接收方到非请求URL的位置来完成请求或标识新的资源
    Pragma              Pragma: no-cache                包括实现特定的指令,它可应用到响应链上的任何接收方
    Proxy-Authenticate          Proxy-Authenticate: Basic        它指出认证方案和可应用到代理的该URL上的参数
    • Image.png
      Image.png

6.3 缓存机制逻辑图

  • 摘自网络

    • Image.png
      Image.png
  • 02 | 网络编程模型:认识客户端-服务器网络模型的基本概念

    • https://blog.csdn.net/qq_37756660/article/details/133862522
贡献者: yangchong211
上一篇
4.1请求网络过程分析
下一篇
4.3Curl实践技巧用法