- 博主简介:想进大厂的打工人
- 博主主页:@xyk:
- 所属专栏: JavaEE初阶
目录
文章目录
一、HTTP概述
1.1 什么是HTTP
1.2 理解应用层协议
二、抓包工具fiddler的使用
2.1 几个需要注意的点
2.2 fiddler的原理
2.3 fiddler的使用技巧
三、HTTP请求(Request)
3.1 认识URL
3.2 认识方法(method)
3.3 POST和GET的区别
3.4 认识请求“报头”(header)
3.5 关于Cookie的几个问题
3.6 通过 ajax 构造HTTP请求(跨域问题)
四、HTTP响应
4.1 状态码
一、HTTP概述
1.1 什么是HTTP
HTTP (全称为 "超文本传输协议") 是一种应用非常广泛的 应用层协议,目前主要使用的是HTTP1.1和HTTP2.0, 在本篇中主要介绍的是HTTP1.1
版本, HTTP往往是基于传输层的TCP
协议实现的.
所谓 “超文本” 的含义, 就是传输的内容不仅仅是文本(比如 html, css 这些个就是文本), 还可以是一些其他的资源, 比如图片, 视频, 音频等二进制的数据.
我们平时打开一个网站, 就是通过 HTTP 协议来传输数据的
当我们在浏览器中输入一个 搜狗搜索的 "网址" (URL) 时, 浏览器就给搜狗的服务器发送了一个 HTTP 请求, 搜狗的服务器返回了一个 HTTP 响应.
这个响应结果被浏览器解析之后, 就展示成我们看到的页面内容. (这个过程中浏览器可能会给服务器发送多个 HTTP 请求, 服务器会对应返回多个响应, 这些响应里就包含了页面 HTML, CSS, JavaScript, 图片, 字体等信息)~~
1.2 理解应用层协议
前面所学的 TCP/IP 解决的是数据传送,相当于快递的功能,那么快递到达了,我们应该如何使用?那么应用层协议就相当于(说明书),不关心通信细节,关心应用细节的~~HTTP就是其中最经典的应用层协议!!!
二、抓包工具fiddler的使用
我们要想看到HTTP协议的详细交互过程就需要借助第三方工具对HTTP进行抓包,Fiddle
是一款专门抓取HTTP/HTTPS包的工具, 下载安装起来很方便, 去官网下载.
官网:https://www.telerik.com/fiddler.
我们也可以通过 chrome 的开发者工具观察这个现象~~
2.1 几个需要注意的点
1.刚下载完成,打开,会弹出一个框框
直接点击yes就可以~~
2.Fiddle本质上是处在一个 “代理” 的角色, 是有可能和其他的代理冲突的, 使用的时候要关闭其他的代理程序(包括一些浏览器插件).
3.当下互联网上的绝大部分服务器使用的都是https
(基于http的进化版协议), Fiddle默认是不能抓取https包的, 需要我们手动设置一下并且安证装书, 操作如下:
然后将下图中的选项全部勾上, 点击OK, 此时会有一个窗口跳出来提示安转证书, 这里一定要点yes, 不然就要重装Fidder了.
如果再不行,就点击右边那个Actions,信任一下证书就行~~
2.2 fiddler的原理
Fiddler 相当于一个 "代理".浏览器访问 sogou.com 时, 就会把 HTTP 请求先发给 Fiddler, Fiddler 再把请求转发给 sogou 的服务器.当 sogou 服务器返回数据时, Fiddler 拿到返回数据, 再把数据交给浏览器.因此 Fiddler 对于浏览器和 sogou 服务器之间交互的数据细节, 都是非常清楚的
2.3 fiddler的使用技巧
左侧:抓到的包的内容,由于我们无时无刻都才发送请求和响应,这个列表是一直在滚动的
找到想要的包:
- 黑色包响应普通数据
- 蓝色包响应的是html
- 看域名
- 再看响应的数据长度,一般找长度长的
双击某个包后, 会在右侧显示详细信息, http是有一定的格式的, Fidder按照不同的格式解析会呈现出不同的显示效果, 右侧的上下两栏中, 上面是请求, 下面是对应的响应.
点击Raw
, 在这个模式下可以看到http的本体(最原始的效果).
view in notepad,在记事本中打开~查看更详细的内容
观察上图中响应可以看到里面有一串乱码, 这是为了节省网络带宽, 有的服务器会对响应数据进行压缩变成了二进制数据(进行了重新编码), 点击下面的黄色按钮就可以解压缩显示正常的响应结果.
这里解压缩后得到的文本数据就是百度主页html里面的内容, 这些就是Fidder的基本理解和使用了, 还要补充一下就是并不是所有的数据都可以进行压缩的, 有的数据重新编码之后, 可能体积会更大, 但是像一般的html/js这样的文本文件, 压缩率还是很高的.
三、HTTP请求(Request)
HTTP请求本质上就是给tcp socket
里写了一个符合http格式的字符串
一个http请求数据包,包含四个部分:
- 首行: [方法] + [url] + [版本]
- Header: 请求的属性, 冒号分割的键值对;每组属性之间使用\n分隔
- 空行:header结束标记
- Body: 空行后面的内容都是Body. Body允许为空字符串. 如果Body存在, 则在Header中会有一个Content-Length属性来标识Body的长度;
3.1 认识URL
平时我们俗称的 "网址" 其实就是说的 URL (Uniform Resource Locator 统一资源定位符),每个网站都有自己的URL
URL 基本格式:
URL最关键的四个部分:
https : 协议方案名. 常见的有 http 和 https
- 服务器地址:www.开头,使用DNS可解析的域名,使用:与端口号分割,没用端口号则省略
- 服务器端口号:描述了要访问主机的哪一个应用程序,若为空,浏览器提供默认的端口号,http:80,https:443
- 带层次的路径:描述访问的服务器上指定位置的资源, 不同的路径, 拿到的资源是不同的, 最简单的路径就是一个
/
, 代表的是http服务器的根目录- 查询字符串:是获取资源的时候带的参数, 是以键值对的方式组织(
query string
), 以?
开头, 键值对之间使用&
分割, 键和值之间使用=
分割
此时访问csdn,url就分为四个部分~~?后面代表要查询的字符串
3.2 认识方法(method)
请求行中的方法是用来告知服务器请求意图的HTTP方法, 不同的方法描述了不同的语义, 有着不同的意图, 比如GET
表示获取一个资源, POST
表示提交一个资源, 在实际开发中最常用的也是这两个方法~
1.GET方法
GET 是最常用的 HTTP 方法. 常用于获取服务器上的某个资源.
- 在浏览器中直接输入 URL, 此时浏览器就会发送出一个 GET 请求.
- 另外, HTML 中的 link, img, script 等标签, 也会触发 GET 请求.
- form表单也可以触发 GET 请求
- JS中的ajax也可以触发 GET 请求
GET的请求报文首行的第一部分为GET, URL的query string
可以为空, 也可以不为空, header
部分有若干个键值对结构, body
部分为空.
2.POST方法
POST
方法也是一种常见的方法, 多用于提交用户输入的数据给服务器(例如登陆页面跳转的时候会涉及到POST)
- 通过from表单可以构造 POST 请求
- 使用JS的ajax也可以构造 POST 请求
POST的请求报文首行的第一部分为POST, URL的query string一般为空(也可以不为空), header部分有若干个键值对结构, body部分一般不为空, body内的数据格式通过header中的Content-Type指定, body的长度由header中的Content-Length指定, 也就是说body中存放要传输的数据~~
3.其他方法
- PUT 与 POST 相似,只是具有幂等特性,一般用于更新
- DELETE 删除服务器指定资源
- OPTIONS 返回服务器所支持的请求方法
- HEAD 类似于GET,只不过响应体不返回,只返回响应头
- TRACE 回显服务器端收到的请求,测试的时候会用到这个
- CONNECT 预留,暂无使用
这些方法的 HTTP 请求可以使用 ajax 来构造
任何一个能进行网络编程的语言都可以构造 HTTP 请求. 本质上就是通过 TCP socket 写入一个符
合 HTTP 协议规则的字符串
3.3 POST和GET的区别
其实GET
和POST
是没有本质区别的, 在大部分场景下彼此之间都可以相互进行替代, GET可以实现POST所具有的特性, 同样POST也可以实现GET所具有的特性, 这两个方法细节上的差别如下:
- GET习惯表示“获取一个数据”,POST习惯表示“提交一个数据”
- GET一般没用body,需要携带的数据放到URL中的查询字符串中,POST一般没有body
- GET可以设置成幂等的,POST无要求,幂等的意思就是每次输入相同的请求,得到的结果都是相同的,即输入一定,输出也一定
- GET可缓存(前提是幂等的),POST则不能
- GET请求可以被浏览器收藏,POST则不能
关于他们两个的区别, 还有一些说法在现在看来是有些争议的, 比如有说法说GET请求所能传输的数据量存在上限(1KB, 2KB, 1024KB等版本), 这些其实是在早期实现浏览器/服务器的时候弄了这样的限制, 但实际上RFC标准文档中对于HTTP GET请求的长度上限是没有明确规定的,POST和GET都没有长度限制!
还有说POST比GET更安全的, 得出这个结论的依据是如果使用GET请求进行登录, 此时用户名和密码就通过query string来传递, 就会出现在浏览器中的地址栏中会被别人看到, 但实际上, 安全的核心要素是加密, 安全指的是如果黑客窃取数据, 敏感信息不会泄露, 所以这个说法也是不太靠谱的!
3.4 认识请求“报头”(header)
header 的整体的格式也是 "键值对" 结构.每个键值对占一行. 键和值之间使用分号分割
- Host
这个字段描述了客户端最终要访问的目标服务器, 这里的内容大概率和URL
是一样的, 也有一定的情况是不一样的.
- Content-Length
描述了body
中的数据长度.
- Content-Type
描述了描述了body中数据的格式, 这里的取值是非常多, 比如值为 application/json说明body中的内容是和应用程序相关的json格式的数据, application/x-www-form-urlencoded是from标签构造的body的数据格式, multipart/form-dataf也是from表单提交的数据格式(在 form 标签中加上 enctyped="multipart/form-data", 通常用于提交图片/文件); 还有text/html, text/css, image/jpg等…
比如:
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="text"
title
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="file"; filename="chrome.png"
Content-Type: image/png
PNG ... content of chrome.png ...
------WebKitFormBoundaryrGKCBY7qhFd3TrwA-
{"username":"123456789","password":"xxxx","code":"jw7l","uuid":"d110a05ccde64b16
a861fa2bddfdcd15"}
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/91.0.4472.77 Safari/537.36
- User-Agent(简称UA)
描述了用户用的浏览器和系统端口号,形如:
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/91.0.4472.77 Safari/537.36
其中 Windows NT 10.0; Win64; x64 表示操作系统信息
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36 表示浏览器信
息
- Referer
描述了当前页面的来源, 如果直接在浏览器地址栏中输入URL, 或者直接通过收藏夹访问页面时是没有Referer
的.
- Cookie
Cookie 中存储了一个字符串, 这个数据可能是客户端(网页)自行通过 JS 写入的, 也可能来自于服务器(服务器在 HTTP 响应的 header 中通过 Set-Cookie 字段给浏览器返回数据).本质:浏览器本地存储用户自定义数据的关键机制
往往通过这个字段实现“身份标识“的功能,每个不同的域名下都可以有不同的 Cookie, 不同网站之间的 Cookie 并不冲突.
这部分内容也是由程序员自定义的, 我们大概率是看不懂的, 只有开发这部分程序代码的程序员才知道, Cookie在存是时候是按照浏览器+域名的维度来进行细分的, 不同的浏览器有不同的Cookie, 同一个浏览器不同的域名, 对应的也是不同的Cookie, Cookie里面的除了键值对(域名)以外还有过期时间(有效期), 路径等信息, 比如有很多的网站, 登录之后就自动记录了登录状态, 在有效期内访问就不需要重复登录了.
3.5 关于Cookie的几个问题:
1.Cookie从哪来?
Cookie从服务器来,浏览器访问服务器时,服务器通过Set-Cookie字段,把Cookie键值对返回给浏览器,不一定只是在第一次访问的时候返回Cookie!!!Cookie存储在浏览器
2.Cookie到哪去?
会在下场请求的时候把Cookie发给服务器,浏览器只是暂存
3.Cookie有啥用?
服务器可以通过Cookie区分不同客户端来提供不同服务,身份识别~~
3.6 通过 ajax 构造HTTP请求(跨域问题)
ajax 全称 Asynchronous Javascript And XML, 是 2005 年提出的一种 JavaScript 给服务器发送
HTTP 请求的方式,特点是可以不需要 刷新页面/页面跳转 就能进行数据传输
Asynchronous:异步,计算机中,一个术语,会有很多种含义!!
1.同步 和 互斥(加锁的场景)一个线程加锁了,其他线程就要等待,称为同步!
2.同步 和 异步(IO的场景)异步就好比去饭店点菜,点完菜找个地方坐下做别的事情,等待菜好了老板直接给端上来,请求的发起者不关心结果,而是由被请求着把结果送给发起者;同步就是菜好了,自己去拿,自行获取响应!
代码示例:
$.ajax({
method: 'get',
url: '/info',
callback: function (body, status) {
console.log(status);
console.log(body);
}
});
callback称为回调函数,会在服务器返回一个正确的响应的时候,被浏览器自动执行,这个执行过程就是”异步“的.
之前我们学过的集合类中的优先级队列,Comparable(compareTo),Comparator(compare),多线程中的重写 run 方法/lambda 表达式,这些都是回调函数.
ajax虽然有诸多优势,但是有一个非常重要的问题,跨域问题,在我们上面写的代码, 是不能运行的!!
现在运行的ajax代码页面的域名是 abc.com,但是ajax里的请求,访问的域名是 def.com,这俩域名不一样的话,哪怕服务器给你返回数据,浏览器还是不能处理,还是要报错,这个东西不是bug,而是浏览器为了限制安全问题,引入的保护机制~~~
四、HTTP响应
基本格式:
http响应的的报文格式由响应行, 响应报头(header), 响应正文(body)这三部分组成, 报头与正文之间使用空行做标记进行分隔.
一个http响应数据包,包括:
- 首行: 协议版本+状态码+状态码描述,用空格分隔
- Header: 响应的属性, 冒号分割的键值对;每组属性之间使用\n分隔
- 空行:header结束标记
- Body: 空行后面的内容都是Body. Body允许为空字符串. 如果Body存在, 则在Header中会有一个Content-Length属性来标识Body的长度;
4.1 状态码:
状态码表示访问一个页面的结果. (是访问成功, 还是失败, 还是其他的一些情况...).
状态码的类别如下:
下面介绍一下常见的状态码:
- 200 OK
表示从客户端发来的请求在服务器端被正常处理了.抓包抓到的大部分结果都是 200.
3XX 重定向: 3XX 响应结果表明浏览器需要执行某些特殊的处理以正确处理请求.
这里注意理解一下 “重定向”, 就相当于手机号码中的 “呼叫转移” 功能,比如我本来的手机号是 186-1234-5678, 后来换了个新号码 135-1234-5678, 那么不需要让我的朋友知道新号码,只要我去办理一个呼叫转移业务, 其他人拨打 186-1234-5678 , 就会自动转移到 135-1234-5678上.
- 301 Moved Permanently
永久重定向. 当浏览器收到这种响应时, 后续的请求都会被自动改成新的地址.
- 302 Move temporarily
临时重定向.
4XX 客户端错误: 4XX 的响应结果表明客户端是发生错误的原因所在.
- 403 Forbidden
该状态码表明对请求资源的访问被服务器拒绝了, 有的页面通常需要用户具有一定的权限才能访问.
- 404 Not Found
该状态码表明访问的资源不存在.
5XX 服务器错误: 5XX 的响应结果表明服务器本身发生错误.
- 500 Internal Server Error
该状态码表明服务器端在执行请求时发生了错误, 一般是服务器的代码执行过程中遇到了一些特殊情况(服务器异常崩溃)会产生这个状态码.
- 504 Gateway Timeout
该状态码表示访问超时了, 可以理解为服务器响应时间太久(长时间未响应)