• JavaEE之HTTP协议 Ⅰ



    前言

    网络技术中,最核心的概念,就是"协议",HTTP就是应用层典型的协议
    应用层,很多时候需要程序员自定义应用层协议,也有一些现成的协议,供我们直接使用~

    HTTP就是其中的"佼佼者"

    1. 浏览器和服务器的交互(打开网页)大概率就是HTTP协议
    2. 手机APP喝服务器之间的交互,也大概率都是HTTP协议
    3. 服务器之间的相互调用,也可以使用HTTP

    最新的版本是HTTP 3.0,但是当前最常见的版本,还是HTTP1.1,以下也主要介绍1.1版本

    在浏览器中输入一个"网址",稍等片刻就看到了网页,这个过程中,就是通过HTTP和服务器进行了交互~
    在这里插入图片描述

    在这里插入图片描述

    HTTP这个协议,是属于最典型的"一问一答"模型的协议

    学习HTTP协议,主要学习的内容,就是HTTP报文格式~
    报文格式就描述了一个HTTP请求是啥样的,以及相应是啥样的~

    在这里插入图片描述

    此处需要使用"抓包工具"来捕获请求交互的详细情况~~

    抓包工具"是个特殊的软件,相当于一个"代理程序”,浏览器给服务器发的请求就会经过这个代理程序,进一步就能分析出请求和响应的结果如何~

    代理:找个人跑腿~

    我和老板进行了哪些交易,这个时候,跑腿(代理)是非常清楚的~

    作为程序员,通过代理,就可以知道浏览器和服务器之间具体的交互细节了~

    谈到代理,代理,还分两种:

    • 正向代理(给客户端提供服务的,和客户端关系紧密),站在服务器的角度,正向代理把真实的客户端给隐藏起来了,服务器不知道真实的客户端是啥
    • 反向代理(给服务器提供服务的,和服务器关系紧密),站在客户端的角度,反向代理把真实的服务器给隐藏起来了,客户端不知道真实的服务器是啥

    使用抓包工具,来分析HTTP协议的工作过程~
    抓包工具有很多,我使用的是fiddler(其他的一些,wireshark,Charles,chrome的开发者工具等等…也可以)


    简单介绍Fiddler:在这里插入图片描述

    左侧区域是抓到的请求 列表

    双击左侧某个你想关注的请求详情,就会在右侧窗口显示出请求的具体情况

    点击右上角的raw标签页,显示HTTP请求最原始的样子

    点击右下角的raw标签页,HTTP响应的最原始的样子

    由于响应数据,可能体积较大,服务器通常会返回一个"压缩"后的结果


    小tips:如果抓不到很多请求的解决办法:

    1. 需要开启fiddler抓取HTTPS的功能!! 现在互联网上纯HTTP很少了,更多的是HTTPS,HTTPS可以理解成升级版本的HTTP,在HTTP的基础上,加了个加密层

    在这里插入图片描述
    在这里插入图片描述

    1. 如果开启了上述HTTPS也安装了根证书,还是抓不到~ 检查电脑上是否安装了其他的代理程序/代理作用的浏览器插件,fq工具/游戏加速器/steam++,本质上都是代理,这些程序都会和fiddler打架,无法同时运行!!
      使用fiddler务必要把其他的代理程序关闭/禁用~

    一、协议格式总结

    在这里插入图片描述
    对照着抓包结果看一下请求情况:

    GET https://www.sogou.com/ HTTP/1.1
    Host: www.sogou.com
    Connection: keep-alive
    Cache-Control: max-age=0
    sec-ch-ua: "Microsoft Edge";v="107", "Chromium";v="107", "Not=A?Brand";v="24"
    sec-ch-ua-mobile: ?0
    sec-ch-ua-platform: "Windows"
    Upgrade-Insecure-Requests: 1
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 Edg/107.0.1418.42
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
    Sec-Fetch-Site: cross-site
    Sec-Fetch-Mode: navigate
    Sec-Fetch-User: ?1
    Sec-Fetch-Dest: document
    Referer: https://cn.bing.com/
    Accept-Encoding: gzip, deflate, br
    Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
    Cookie: SUID=DCD4D38BD352A00A0000000062FB75D6; usid=2EC2C871ED18A00A000000006354C27B; SUV=1667727332968362; browerV=3; osV=1; IPLOC=CN6100; ABTEST=0|1668496465|v17; SNUID=7C6D0FB866638A1B7CD61A0F67F3B218; ld=pyllllllll20t8ezlllllp285VolllllTLkapZllll9lllllRZlll5@@@@@@@@@@; LSTMV=297%2C26; LCLKINT=6081
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    以上是一个完整的HTTP请求的样子~
    要构造一个HTTP请求,本质上就是往一个TCP socket中,按照下列格式来写入数据即可~

    HTTP是一个文本格式的协议

    1. 首行:
      在这里插入图片描述

    2. 请求头 header

    Host: www.sogou.com
    Connection: keep-alive
    Cache-Control: max-age=0
    sec-ch-ua: "Microsoft Edge";v="107", "Chromium";v="107", "Not=A?Brand";v="24"
    sec-ch-ua-mobile: ?0
    sec-ch-ua-platform: "Windows"
    Upgrade-Insecure-Requests: 1
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 Edg/107.0.1418.42
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
    Sec-Fetch-Site: cross-site
    Sec-Fetch-Mode: navigate
    Sec-Fetch-User: ?1
    Sec-Fetch-Dest: document
    Referer: https://cn.bing.com/
    Accept-Encoding: gzip, deflate, br
    Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
    Cookie: SUID=DCD4D38BD352A00A0000000062FB75D6; usid=2EC2C871ED18A00A000000006354C27B; SUV=1667727332968362; browerV=3; osV=1; 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    这里是一个按行组织的键值对,每一行,是一个键值对,键和值之间使用 : 空格 来分割
    这里的键都是有固定含义的~

    1. 空行
      一个HTTP请求的header可以有若干个,就使用空行作为header的结束标记,类似于链表的null

    2. 正文 body
      有的请求有,有的没有,承载一些具体的数据,可能是json格式的,也可能是其他格式的

    {"SessionId": "E25091DB353ABD99281B8635D8A845C8","AppId": "Edge_Win32","Language1": "zh-CN","Content": [{"TileId": "en-US","RevisionId": "0","TileElements": [{"LanguageId": "en-US","Text": "3. 空行","TextUnit": 8}]}],"Descriptors":[{"Name": "FlightIds","Value": "wac-wordeditorservicemultiplegrammarcritiquesperse1nce-treatment"},{"Name": "LicenseType","Value": "NoLicense"}]}
    
    • 1

    在这里插入图片描述

    完整的HTTP响应的格式~

    1. 首行
      在这里插入图片描述

    2. 响应报头 header 同样也是键值对的结构~

    Server: nginx
    Date: Wed, 16 Nov 2022 07:49:53 GMT
    Content-Type: text/html; charset=utf-8
    Connection: keep-alive
    Vary: Accept-Encoding
    Set-Cookie: black_passportid=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=.sogou.com
    Pragma: No-cache
    Cache-Control: max-age=0
    Expires: Wed, 16 Nov 2022 07:49:53 GMT
    UUID: 8bce19ac-2795-40e5-a59e-f59e38db5c66
    Content-Length: 14927
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    1. 空行
      作为header的结束标记~
    2. 正文
      正文可以是json数据,可以是html,也可以是cmd 等等…

    在这里插入图片描述

    接下来介绍HTTP协议中的细节~

    二、认识URL

    URL : 唯一资源定位符(用这个来找到网络上的资源)
    URI : 唯一资源标识符(用这个来区分一个网络上的资源)
    这俩概念非常相似,很多时候,并不会显式区分~

    URL 里面是啥样子的,是有"RFC标准文档"来进行描述的~

    RFC标准文档: 描述了很多网络中的协议标准,包括IP,TCP,UDP,HTTP …

    在这里插入图片描述
    URL重要的部分:

    1. IP地址地址+端口号[基础]
    2. 带层次的路径[开发中常用]
    3. 查询字符串[开发中常用]

    🎐URL encode / decode :

    URL中已经包含了一些特殊含义的付好了,比如 : / ? @ ....
    万一query stringvalue中,也包含了这些特殊符号会咋样?
    很可能会有问题!! (浏览器可能会错误的识别URL,服务器也可能会错误的解析URL)
    非常类似于编程语言里的变量名不能是"关键字"
    URL encode / decode 本质上就是把特殊符号进行转义了,这里转义的范围不仅仅是这些特殊符号,还有汉字~
    转义规则:把待转义的字符串,把每个字符的十六进制表示前加上个%


    把原始的字符,转成转义后的字符 => URL encode(编码)
    把转义后的字符还原成原始的字符 => URL decode(解码)

    三、认识"方法"(method)

    HTTP中非常重要的部分~
    可以把 方法 理解成 -> 你这个请求想干啥

    • GET
    • POST

    熟悉了GET POST 就可以应对90%以上的场景了

    1.GET

    最常用的的HTTP请求方法~

    1. 浏览器地址栏直接输入URL,此时就会触发GET
    2. html里面的link,a,img,script也会触发GET请求
      href/src都会引入一个外部的资源~
      本质上就是浏览器会重新发送一个GET请求,来从服务器拿到对应的数据~
      一个浏览器加载出一个页面,往往要经过多重HTTP请求的交互~
      比如搜索引擎会一次搜索出很多结果!

    浏览器缓存:
    浏览器在加载页面的时候,往往要加载这个页面依赖的很多资源,css,图片,js等…加载这些资源,显然是需要消耗不少时间的~

    为了提高页面加载效率,浏览器就会对加载过的这些css图片,js进行缓存(保存在你本地的磁盘上)下次再访问同一个网页,之前的css,图片,js就不必重新从网络加载,而是直接读硬盘即可~
    使用ctrl+f5强制刷新,就可以让浏览器不走缓存,直接强制从网络上获取资源~~

    1. form表单 htmlform标签,可以构造出GET请求
    2. ajax(后面在"如何构造HTTP请求"中讲)

    GET请求的特点

    GET https://www.sogou.com/ HTTP/1.1
    Host: www.sogou.com
    Connection: keep-alive
    Cache-Control: max-age=0
    sec-ch-ua: "Microsoft Edge";v="107", "Chromium";v="107", "Not=A?Brand";v="24"
    sec-ch-ua-mobile: ?0
    sec-ch-ua-platform: "Windows"
    Upgrade-Insecure-Requests: 1
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 Edg/107.0.1418.42
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
    Sec-Fetch-Site: same-origin
    Sec-Fetch-Mode: navigate
    Sec-Fetch-User: ?1
    Sec-Fetch-Dest: document
    Accept-Encoding: gzip, deflate, br
    Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
    Cookie: SUID=DCD4D38BD352A00A0000000062FB75D6; usid=2EC2C871ED18A00A000000006354C27B; SUV=1667727332968362; browerV=3; osV=1; IPLOC=CN6100; ABTEST=0|1668496465|v17; SNUID=7C6D0FB866638A1B7CD61A0F67F3B218; ld=pyllllllll20t8ezlllllp285VolllllTLkapZllll9lllllRZlll5@@@@@@@@@@; LSTMV=297%2C26; LCLKINT=6081
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 首行的第一部分为 GET
    • URLquery string 可以为空, 也可以不为空.
    • header 部分有若干个键值对结构.
    • body 部分为空
      如果需要给服务器传递一些参数,这些参数通常就是通过querystring来传过去的

    2.POST

    产生POST途径

    1. form
    2. ajax

    POST 请求的特点

    POST请求:

    POST https://edu.bitejiuyeke.com/tms/login HTTP/1.1
    Host: edu.bitejiuyeke.com
    Connection: keep-alive
    Content-Length: 117
    sec-ch-ua: "Microsoft Edge";v="107", "Chromium";v="107", "Not=A?Brand";v="24"
    sec-ch-ua-mobile: ?0
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 Edg/107.0.1418.42
    Access-Control-Allow-Methods: PUT,POST,GET,DELETE,OPTIONS
    Content-Type: application/json;charset=UTF-8
    Access-Control-Allow-Origin: *
    Accept: application/json, text/plain, */*
    Access-Control-Allow-Headers: Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild
    sec-ch-ua-platform: "Windows"
    Origin: https://edu.bitejiuyeke.com
    Sec-Fetch-Site: same-origin
    Sec-Fetch-Mode: cors
    Sec-Fetch-Dest: empty
    Referer: https://edu.bitejiuyeke.com/login
    Accept-Encoding: gzip, deflate, br
    Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
    
    {"username":"xxxxxxxxxxx","password":"xxxxxxx","uuid":"6cda4adb156c4f8ebe13263f069aa0e3","status":0}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    1. 方法叫做POST
    2. url通常是没有query string
    3. 也是有若干header,键值对的形式
    4. body这里通常是有的~ (body的数据格式有很多种)
      POST 在传递信息给服务器的时候,通常就会把信息放到body中~

    在这里插入图片描述

    GETPOST 的区别[经典面试题]

    第一步,先盖棺定论:GET和POST没有本质区别,使用GET实现的场景基本都可以使用POST代替,使用POST实现的场景,也可以用GET来代替
    第二步,再来谈细节上的区别~

    1. GET的语义,是从"服务器获取个数据",POST的语义,是"往服务器上提交个数据"(这里是建议你设计的时候采取这样的语义~ )
    2. 使用习惯上,给服务器传递的数据,GET通常是放在urlquery string中,POST通常是放在body(GET能否把数据放在body里? 也是可以的,不过很少见,浏览器不一定能支持,其他的http客户端是可以支持的,POST能否把数据放在query string里? 完全可以~但是也少见,浏览器啥的都是支持的)
    3. GET请求建议实现成"幂等"的!! POST一般则不要求实现成"幂等"(输入是确定的,输出结果也就是确定的),设置服务器的时候,就需要提供一些"接口/api",api传入的参数,就视为是输入,api返回的结果,就视为是输出,基于GETapi一般会建议设置成幂等的,基于POSTapi则无要求,但也只是建议
    4. 在幂等的基础上,GET的请求结果是可以被缓存的,POST则一般不会缓存(浏览器默认的行为,如果GET确实是幂等的,就不必处理,就让浏览器缓存,如果当前GET不是幂等的,就需要通过特殊技巧避免浏览器产生缓存 [典型的技巧就是让每次GET请求的url都不相同,通过特殊的 query string 来保证url不同])

    总结

    在这里插入图片描述

    你可以叫我哒哒呀
    本篇到此结束
    “莫愁千里路,自有到来风。”
    我们顶峰相见!
  • 相关阅读:
    竞赛选题 基于深度学习的视频多目标跟踪实现
    浏览器中的history详解
    农产品直销平台/农场品销售系统
    解密高性能查询!小米亲授:如何轻松查出1000条数据的后十条前7条?
    爱创科技X腾讯安全:追溯生态体系赋能酒企数智化转型
    linux性能分析(五)CPU篇(一)基础
    币圈是什么意思?币圈开发
    淘宝/天猫淘宝评论问答列表接口 API
    图神经网络基础理论及实操
    如何分析排序算法
  • 原文地址:https://blog.csdn.net/m0_58437435/article/details/127717522