【JavaEE】HTTP 协议详解 ( 使用fiddler进行抓取http请求/相应包)

目录

  • 1. HTTP 协议概念
  • 2. HTTP 协议的工作过程
  • 3. HTTP 协议格式
    • 3.1 Fiddler抓包工具的原理
    • 3.2 协议格式总结
  • 4. HTTP 请求 (Request)
    • 4.1 URL 基本格式
    • 4.2 query string
    • 4.3 URL encode
    • 4.4 认识 "方法" (method)
      • 4.4.1 GET 方法
      • 4.4.2 POST 方法
      • 4.4.3 其他方法
      • 4.4.4 经典面试题: 谈谈 GET 和 POST 的区别
    • 4.5 认识请求 "报头" (header)
    • 4.66 认识请求 "正文" (body)
  • 5. HTTP 响应详解
    • 5.1 认识 "状态码" (status code)
    • 5.2 认识响应 "报头" (header)
    • 5.3 认识响应 "正文" (body)
  • 6. 构造 HTTP 请求
    • 6.1 通过 form 表单构造 HTTP 请求
    • 6.2 通过 ajax 构造 HTTP 请求

1. HTTP 协议概念

HTTP (全称为 “超文本传输协议”) 是一种应用非常广泛的 应用层协议.
所谓 “超文本” 的含义, 就是传输的内容不仅仅是文本(比如 html, css 这个就是文本), 还可以是一些
其他的资源, 比如图片, 视频, 音频等二进制的数据.
HTTP 诞生与1991年. 目前已经发展为最主流使用的一种应用层协议
【JavaEE】HTTP 协议详解 ( 使用fiddler进行抓取http请求/相应包)_第1张图片

HTTP 往往是基于传输层的 TCP 协议实现的. (HTTP1.0, HTTP1.1, HTTP2.0 均为TCP, HTTP3 基于 UDP 实现)
目前我们主要使用的还是 HTTP1.1 和 HTTP2.0 . 本篇博客讨论的 HTTP 以 1.1 版本为主.

我们平时打开一个网站, 就是通过 HTTP 协议来传输数据的。

2. HTTP 协议的工作过程

当我们在浏览器中输入一个 “网址”, 此时浏览器就会给对应的服务器发送一个 HTTP 请求. 对方服务器收
到这个请求之后, 经过计算处理, 就会返回一个 HTTP 响应.
【JavaEE】HTTP 协议详解 ( 使用fiddler进行抓取http请求/相应包)_第2张图片

3. HTTP 协议格式

HTTP 是一个文本格式的协议. 可以通过 Chrome 开发者工具或者 Fiddler 抓包, 分析 HTTP 请求/响应的
细节.

3.1 Fiddler抓包工具的原理

Fiddler 相当于一个 “代理”.
浏览器访问 sogou.com 时, 就会把 HTTP 请求先发给 Fiddler, Fiddler 再把请求转发给 sogou 的服务器.
当 sogou 服务器返回数据时, Fiddler 拿到返回数据, 再把数据交给浏览器. (中间人)
因此 Fiddler 对于浏览器和 sogou 服务器之间交互的数据细节, 都是非常清楚的.
【JavaEE】HTTP 协议详解 ( 使用fiddler进行抓取http请求/相应包)_第3张图片
打开一个 bilibili 抓包结果如下:

HTTP请求 :
【JavaEE】HTTP 协议详解 ( 使用fiddler进行抓取http请求/相应包)_第4张图片

  • 首行: [方法] + [url] + [版本]
  • Header: 请求的属性, 冒号分割的键值对;每组属性之间使用\n分隔;遇到空行表示Header部
    分结束
  • Body: 空行后面的内容都是Body. Body允许为空字符串. 如果Body存在, 则在Header中会有
    一个Content-Length属性来标识Body的长度;

HTTP响应 :
【JavaEE】HTTP 协议详解 ( 使用fiddler进行抓取http请求/相应包)_第5张图片

  • 首行: [版本号] + [状态码] + [状态码解释]
  • Header: 请求的属性, 冒号分割的键值对;每组属性之间使用\n分隔;遇到空行表示Header部
    分结束
  • Body: 空行后面的内容都是Body. Body允许为空字符串. 如果Body存在, 则在Header中会有
    一个Content-Length属性来标识Body的长度; 如果服务器返回了一个html页面, 那么html页
    面内容就是在body中.

3.2 协议格式总结

【JavaEE】HTTP 协议详解 ( 使用fiddler进行抓取http请求/相应包)_第6张图片

问题 : 为什么 HTTP 报文中要存在 “空行”?
因为 HTTP 协议并没有规定报头部分的键值对有多少个. 空行就相当于是 “报头的结束标记”, 或者
是 “报头和正文之间的分隔符”.
HTTP 在传输层依赖 TCP 协议, TCP 是面向字节流的. 如果没有这个空行, 就会出现 “粘包问题”.

4. HTTP 请求 (Request)

4.1 URL 基本格式

平时我们俗称的 “网址” 其实就是说的 URL (Uniform Resource Locator 统一资源定位符).
互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它.
【JavaEE】HTTP 协议详解 ( 使用fiddler进行抓取http请求/相应包)_第7张图片

一个具体的 URL:
在这里插入图片描述

  • https : 协议方案名. 常见的有 http 和 https, 也有其他的类型. (例如访问 mysql 时用的jdbc:mysql )
  • user:pass : 登陆信息. 现在的网站进行身份认证一般不再通过 URL 进行了. 一般都会省略
  • v.bitedu.vip : 服务器地址. 此处是一个 “域名”, 域名会通过 DNS 系统解析成一个具体的 IP 地址.
    (通过 ping 命令可以看到, v.bitedu.vip 的真实 IP 地址为 118.24.113.28 )
  • 端口号: 上面的 URL 中端口号被省略了. 当端口号省略的时候, 浏览器会根据协议类型自动决定使用
    哪个端口. 例如 http 协议默认使用 80 端口, https 协议默认使用 443 端口.
  • /personInf/student : 带层次的文件路径.
  • userId=10000&classId=100 : 查询字符串(query string). 本质是一个键值对结构. 键值对之间使
    用 & 分隔. 键和值之间使用 = 分隔.
  • 片段标识:此URL省略了片段标识,片段标识主要用于页面内跳转

【JavaEE】HTTP 协议详解 ( 使用fiddler进行抓取http请求/相应包)_第8张图片

注意:可以使用cmd ping命令查看域名对应的ip地址是多少 :
【JavaEE】HTTP 协议详解 ( 使用fiddler进行抓取http请求/相应包)_第9张图片

4.2 query string

query string 中的内容是键值对结构. 其中的 key 和 value 的取值和个数, 完全都是程序猿自己约
定的. 我们可以通过这样的方式来自定制传输我们需要的信息给服务器.

4.3 URL encode

像 / ? : 等这样的字符, 已经被url当做特殊意义理解了. 因此这些字符不能随意出现.
比如, 某个参数中需要带有这些特殊字符, 就必须先对特殊字符进行转义.
(一个中文字符由 UTF-8 或者 GBK 这样的编码方式构成, 虽然在 URL 中没有特殊含义, 但是仍然需
要进行转义. 否则浏览器可能把 UTF-8/GBK 编码中的某个字节当做 URL 中的特殊符号. )

转义的规则如下: 将需要转码的字符转为16进制,然后从右到左,取4位(不足4位直接处理),每2位做一
位,前面加上%,编码成%XY格式

列如 :
在这里插入图片描述

  • “+” 被转义成了 “%2B”

urldecode就是urlencode的逆过程;

4.4 认识 “方法” (method)

【JavaEE】HTTP 协议详解 ( 使用fiddler进行抓取http请求/相应包)_第10张图片

4.4.1 GET 方法

GET 是最常用的 HTTP 方法. 常用于获取服务器上的某个资源.
在浏览器中直接输入 URL, 此时浏览器就会发送出一个 GET 请求.
另外, HTML 中的 link, img, script 等标签, 也会触发 GET 请求.

GET 请求的特点:

  • 首行的第一部分为 GET
  • URL 的 query string 可以为空, 也可以不为空.
  • header 部分有若干个键值对结构.
  • body 部分为空.

关于 GET 请求的 URL 长度问题 :
HTTP协议标准中没有对 URL 的长度有任何的限制,实际 URL 的长度取决于浏览器的实现和 HTTP 服务器端的实现. 在浏览器端, 不同的浏览器最大长度是不同的, 但是现代浏览器支持的长度一般都很长; 在服务器端, 一般这个长度是可以配置的.

4.4.2 POST 方法

POST 方法也是一种常见的方法. 多用于提交用户输入的数据给服务器(例如登陆页面).
通过 HTML 中的 form 标签可以构造 POST 请求, 或者使用 JavaScript 的 ajax 也可以构造 POST 请求.

POST 请求的特点 :

  • 首行的第一部分为 POST
  • URL 的 query string 一般为空 (也可以不为空)
  • header 部分有若干个键值对结构.
  • body 部分一般不为空. body 内的数据格式通过 header 中的 Content-Type 指定. body 的长度由
    header 中的 Content-Length 指定.

4.4.3 其他方法

  • PUT 与 POST 相似,只是具有幂等特性,一般用于更新
  • DELETE 删除服务器指定资源
  • OPTIONS 返回服务器所支持的请求方法
  • HEAD 类似于GET,只不过响应体不返回,只返回响应头
  • TRACE 回显服务器端收到的请求,测试的时候会用到这个
  • CONNECT 预留,暂无使用

4.4.4 经典面试题: 谈谈 GET 和 POST 的区别

  • 二者本质上没有什么区别( GET 完全可以用于提交数据, POST 也完全可以用于获取数据. )
  • 语义不同: GET 一般用于获取数据, POST 一般用于提交数据.
  • GET 的 body 一般为空, 需要传递的数据通过 query string 传递, POST 的 query string 一般
    为空, 需要传递的数据通过 body 传递
  • GET 请求一般是幂等的(幂等:输入什么就输出什么), POST 请求一般是不幂等的. (如果多次请求得到的结果一样, 就视为请求是幂等的).
  • GET 可以被缓存, POST 不能被缓存. (这一点也是承接幂等性).

补充说明:.

  • 关于幂等性: 标准建议 GET 实现为幂等的. 实际开发中 GET 也不必完全遵守这个规则(主流网
    站都有 “猜你喜欢” 功能, 会根据用户的历史行为实时更新现有的结果.
  • 关于安全性: 有些资料上说 “POST 比 GET 请安全”. 这样的说法是不科学的. 是否安全取决于
    前端在传输密码等敏感信息时是否进行加密, 和 GET POST 无关.
  • 关于传输数据量: 有的资料上说 “GET 传输的数据量小, POST 传输数据量大”. 这个也是不科
    学的, 标准没有规定 GET 的 URL 的长度, 也没有规定 POST 的 body 的长度. 传输数据量多少,
    完全取决于不同浏览器和不同服务器之间的实现区别.
  • 关于传输数据类型: 有的资料上说 “GET 只能传输文本数据, POST 可以传输二进制数据”. 这
    个也是不科学的. GET 的 query string 虽然无法直接传输二进制数据, 但是可以针对二进制数
    据进行 url encode.

4.5 认识请求 “报头” (header)

header 的整体的格式也是 “键值对” 结构.
每个键值对占一行. 键和值之间使用分号分割.

  • Host:表示服务器主机的地址和端口.
  • Content-Length:表示 body 中的数据长度.
  • Content-Type:表示请求的 body 中的数据格式.
  • User-Agent (简称 UA) :表示浏览器/操作系统的属性
  • Referer :表示这个页面是从哪个页面跳转过来的.

Cookie :Cookie 中存储了一个字符串, 这个数据可能是客户端(网页)自行通过 JS 写入的, 也可能来自于服务器(服务器在 HTTP 响应的 header 中通过 Set-Cookie 字段给浏览器返回数据). 往往可以通过这个字段实现 “身份标识” 的功能.

登录过程如图 :
【JavaEE】HTTP 协议详解 ( 使用fiddler进行抓取http请求/相应包)_第11张图片

4.66 认识请求 “正文” (body)

正文中的内容格式和 header 中的 Content-Type 密切相关

5. HTTP 响应详解

5.1 认识 “状态码” (status code)

状态码表示访问一个页面的结果. (是访问成功, 还是失败, 还是其他的一些情况)
以下为常见的状态码.:

  • 200 OK:这是一个最常见的状态码, 表示访问成功.
  • 404 Not Found :没有找到资源
  • 403 Forbidden:表示访问被拒绝. 有的页面通常需要用户具有一定的权限才能访问(登陆后才能访问). 如果用户没有登陆直接访问, 就容易见到 403.
  • 405 Method Not Allowed:前面说到的 HTTP 中所支持的方法, 有 GET, POST, PUT, DELETE 等. 但是对方的服务器不一定都支持所有的方法(或者不允许用户使用一些其他的方法).
  • 500 Internal Server Error:服务器出现内部错误. 一般是服务器的代码执行过程中遇到了一些特殊情况(服务器异常崩溃)会产生这个状态码.
  • 504 Gateway Timeout:当服务器负载比较大的时候, 服务器处理单条请求的时候消耗的时间就会很长, 就可能会导致出现超时的情况.
  • 302 Move temporarily:临时重定向.
    在登陆页面中经常会见到 302. 用于实现登陆成功后自动跳转到主页.
    响应报文的 header 部分会包含一个 Location 字段, 表示要跳转到哪个页面.
  • 301 Moved Permanently:永久重定向. 当浏览器收到这种响应时, 后续的请求都会被自动改成新的地址. 301 也是通过 Location 字段来表示要重定向到的新地址.

状态码小结:
【JavaEE】HTTP 协议详解 ( 使用fiddler进行抓取http请求/相应包)_第12张图片

5.2 认识响应 “报头” (header)

响应报头的基本格式和请求报头的格式基本一致.
类似于 Content-Type , Content-Length 等属性的含义也和请求中的含义一致

Content-Type :响应中的 Content-Type 常见取值有以下几种

  • text/html : body 数据格式是 HTML
  • text/css : body 数据格式是 CSS
  • application/javascript : body 数据格式是 JavaScript
  • application/json : body 数据格式是 JSON

5.3 认识响应 “正文” (body)

正文的具体格式取决于 Content-Type.

6. 构造 HTTP 请求

6.1 通过 form 表单构造 HTTP 请求

form (表单) 是 HTML 中的一个常用标签. 可以用于给服务器发送 GET 或者 POST 请求.

form 的重要参数:

  • action: 构造的 HTTP 请求的 URL 是什么.
  • method: 构造的 HTTP 请求的 方法 是 GET 还是 POST (form 只支持 GET 和 POST).

input 的重要参数:

  • type: 表示输入框的类型. text 表示文本, password 表示密码, submit 表示提交按钮.
  • name: 表示构造出的 HTTP 请求的 query string 的 key. query string 的 value 就是输入框的用户
    输入的内容.
  • value: input 标签的值. 对于 type 为 submit 类型来说, value 就对应了按钮上显示的文本.

整体格式如下:
【JavaEE】HTTP 协议详解 ( 使用fiddler进行抓取http请求/相应包)_第13张图片
详解 :
【JavaEE】HTTP 协议详解 ( 使用fiddler进行抓取http请求/相应包)_第14张图片

【JavaEE】HTTP 协议详解 ( 使用fiddler进行抓取http请求/相应包)_第15张图片
通过一个提交按钮来触发http请求 :
在这里插入图片描述
在这里插入图片描述
点击之后,页面跳转 :
【JavaEE】HTTP 协议详解 ( 使用fiddler进行抓取http请求/相应包)_第16张图片
fiddler抓包http请求如下 :
【JavaEE】HTTP 协议详解 ( 使用fiddler进行抓取http请求/相应包)_第17张图片

  • 注意: 由于我们的服务器的地址是随便写的, 因此无法获取到正确的 HTTP 响应.
  • form 的 action 属性对应 HTTP 请求的 URL
  • form 的 method 属性对应 HTTP 请求的方法
  • input 的 name 属性对应 query string 的 key
  • input 的 内容 对应 query string 的 value

form 发送 POST 请求 :
【JavaEE】HTTP 协议详解 ( 使用fiddler进行抓取http请求/相应包)_第18张图片
fiddler抓包http请求如下 :
【JavaEE】HTTP 协议详解 ( 使用fiddler进行抓取http请求/相应包)_第19张图片
主要的区别:

  • method 从 GET 变成了 POST
  • 数据从 query string 移动到了 body 中.

6.2 通过 ajax 构造 HTTP 请求

ajax 全称 Asynchronous Javascript And XML,特点是可以不需要 刷新页面/页面跳转 就能进行数据传输,在 JavaScript 中可以通过 ajax 的方式构造 HTTP 请求.

从前端角度, 除了浏览器地址栏能构造 GET 请求, form 表单能构造 GET 和 POST 之外, 还可以通过 ajax
的方式来构造 HTTP 请求. 并且功能更强大

Ajax是基于异步等待的方式来进行的,所谓的 异步等待 就是 :调用者发起一个调用请求之后,就不管啦;等到被调用者结果出来之后,再主动通知调用者 ~

首先构造出一个HTTP请求,发给服务器,但是浏览器不确定服务器啥时候才有响应,于是就先不管了,浏览器里面就继续执行其他代码.(该干啥干啥)等到服务器的响应回来了之后,再由浏览器通知对应的JS代码,以回调函数的方式来处理响应 。

基于jQuery构造Ajax请求 :

首先引入jQuery :

  1. 搜索jQuery cdn 查询
  2. 在结果中,找到一个合适的cdn的url
  3. 打开对应的URL,加载出jQuery本体
  4. 复制粘贴到本地文件中,即可引入成功 ~
    【JavaEE】HTTP 协议详解 ( 使用fiddler进行抓取http请求/相应包)_第20张图片
    使用 jQuery的Ajax ,通过 $ 符号,$ 就是jQuery中最核心的对象,jQuery的各种api,都是通过$ 来触发的 ; 通过$来调用ajax函数,参数只有一个,但是是一个“对象” :
    【JavaEE】HTTP 协议详解 ( 使用fiddler进行抓取http请求/相应包)_第21张图片
    对象中的取值 :
  • type :http请求的方法,不仅仅支持get和post,还支持put,delete等其他方法
  • url:对应http请求的url
  • 下面是处理响应的相应回调函数

刚才的ajax请求,抓包如下:
【JavaEE】HTTP 协议详解 ( 使用fiddler进行抓取http请求/相应包)_第22张图片
相应里面是 200 OK,并且body也是html数据 ,但是 浏览器仍然认为这是一个“出错”的请求 :
【JavaEE】HTTP 协议详解 ( 使用fiddler进行抓取http请求/相应包)_第23张图片
出现这个报错的原因,是因为 浏览器 禁止 ajax 进行 跨域访问 (跨域访问:跨越多个域名/服务器)

因为当前的ajax请求中的url,域名是 www.sogou.com ;如果当前页面处在的服务器就是这个域名,页面中再通过ajax请求url,域名为 www.sogou.com 这种就不算是跨域 !

所以当前的ajax请求无法被正确处理,等到部署的页面和ajax的地址都是同一个服务器时候,就可以正常使用ajax发送http请求了 ~

  • http over~✨

你可能感兴趣的:(Java学习之旅,http协议详解,网络编程,http,fiddler,前端)