0


HTTP 协议

✏️作者:银河罐头
📋系列专栏:JavaEE

🌲“种一棵树最好的时间是十年前,其次是现在”

目录

HTTP 是什么

image-20230315153656067

HTTP 协议是应用层最广泛使用的协议之一。

浏览器从服务器获取到页面就是基于 http 协议。HTTP 就是 浏览器 和 服务器 之间的交互桥梁。

目前主要使用的是 HTTP1.1

HTTP 往往是基于传输层的 TCP 协议实现的.

image-20230315155807420

  • sogou.com (网址,URL)

浏览器就会根据这个 URL 构造一个 HTTP 请求,发给服务器。服务器就会返回一个 HTTP 响应(包含了 html, css, js, 图片…)

浏览器再把得到的 html 等数据进行显示出来(渲染)

HTTP 协议 全称是超文本传输协议。

抓包工具的使用

http 协议交互的详细过程,可以借助第三方的工具来看到,称为抓包工具。

这里我使用的是 fiddler, 专注 http,使用起来简单。

image-20230315155541814

image-20230315161015148

立即显示出当前电脑上某个程序使用 http 和 服务器交互的过程。

fiddler 本质上是一个代理程序,使用的时候有 2 个注意事项:

  1. 可能和别的代理程序冲突,使用的时候要关闭其他代理程序(包括一些浏览器插件)

代理

代理就是找个人帮你干活。

举个栗子:

我在寝室里,饿了,但是又懒得下楼,我就让我舍友去超市帮我带一个泡面

image-20230315161846823

如果我自己去超市,也能完成这次交易,但是我懒,就让室友跑腿了,室友相当于就是"代理"。室友对于我和超市老板的交易细节是非常清楚的。

代理还分两种,正向代理和反向代理。

正向代理,代表客户端的代理。

反向代理,代表服务器的代理。

image-20230315164612626

  1. 要想正确抓包,还需要开启 https 功能。

https 是基于 http 搞出来的进化版协议。当前互联网上的绝大部分服务器都是支持 https 的。

而 fiddler 不能抓 https 的包,需要我们手动启用一下 https 并且安装证书。

image-20230315165831413

image-20230315170749822

image-20230315171045601

image-20230315171123483

请求是有一定格式的,fiddler 会按照 http 的格式解析请求,呈现出不同的显示效果,此处就看最原始的效果。

任何一个程序都能使用 http 协议,不仅仅是 浏览器。

HTTP请求:

image-20230315214405150

通过抓包结果,可以看到当前 http 请求,其实是个行文本格式的数据。相比于 tcp 这样的二进制数据,更方便用户进行观察。

压缩是什么原理?

为了表达一个信息,重新进行编码。表达的含义是一样的,重新编码之后,体积就能减小。

HTTP响应:

image-20230315213749141

这个文本数据,就是搜狗首页,html 里的内容。

HTTP 请求

GET https://www.sogou.com/ HTTP/1.1

首行

包含 3 个部分,之间用空格来区分。

GET : HTTP 的方法(method)

https://www.sogou.com/

URL 俗称的网址。

URL, 唯一资源定位符,标识互联网上唯一资源的位置。(资源在哪,在哪个服务器的哪个目录下的哪个文件)

URI,唯一资源标识符,身份标识,为了和别的资源区分开。

HTTP/1.1 : 版本号

认识下 URL

image-20230315215513805

URL 的详细规则由 因特网标准RFC1738 进行了约定.

tcp, ip, udp 协议格式都是由 rfc 文档定义的。

url 不是 http 专属的,很多协议都可以使用 url。

image-20230317203235044

url 最关键的 4 个 部分:

1.域名

2.端口号

3.带层次的文件路径

4.查询字符串

image-20230317211450892

一个 url,有些部分是可以省略的。

image-20230317212419600

image-20230317212620279

一个 HTTP 服务器提供的资源是很多的,不同的路径拿到的资源是不同的。

image-20230317214414625

url 有些字符是由特定含义的,就需要对内容进行重新编码,如果不编码直接写中文,可能浏览器就无法正确识别了。

image-20230317214912514

urlencode 编码

urldecode 解码

HTTP 协议是一个 行文本协议。

认识 “方法” (method)

方法描述了此次请求的语义。

image-20230318112025141

其中最常见的就是 get , post

GET 请求

1.在浏览器地址栏直接输入 url

2.html 里的 link, script, img, a…

3.通过 js 构造 GET 请求

通过 fiddler 抓包一个 GET 请求:

image-20230318113240037

POST 请求

登录,上传文件

比如我 登录 gitee,

用 fiddler 抓包一个 POST请求

image-20230318114903151

HTTP 请求可以分成 4 个部分:

1.首行

2.请求头(header)

3.空行

4.正文(body)

body 里放的是 程序员自定义的信息。

GET 和 POST 之间的差别

经典面试题

首先要明确的是,GET 和 POST 没有本质区别,只是在使用习惯上有差异(大部分场景下,彼此之间都能相互替代).

区别:

1.如果是 GET 请求,一般没有 body;POST 请求一般有 body.

2.GET 可以给 服务器传递一些信息,GET 传递的信息一般放在 query string 里面。POST 传递信息则通过 body。

3.GET 请求一般是用于从服务器获取数据;POST 一般是用于给服务器提交数据。

4.GET 通常会被设计成幂等的,POST 不要求幂等。

幂等,指的是相同的输入,得到的结果是确定的。

5.GET 可以被缓存,POST 一般不能被缓存。(把请求的结果保存下来了,下次再请求时就不用真请求,直接取缓存的结果)

认识请求 “报头” (header)

image-20230318143512825

每一行是一个键值对,键和值之间用 :分割。

  • Host

大概描述了服务器所在的地址和端口。Host 这里的地址和端口,用来描述你最终要访问的目标。这个内容大概率和 url 中是一样的,也有一定情况是不同的。

  • Content-Length 表示 body 中的数据长度. 单位是字节
  • Content-Type 表示请求的 body 中的数据格式.

如果是 GET 请求,没有 body, 就没有Content-Length 和 Content-Type 这俩字段;如果是 POST 请求,有 body ,就有这俩字段。

image-20230318144659844

Content-Type 取值是非常多的。

text/html

text/css

image/png

image/jpg

application/javascript

application/json

User-Agent (简称 UA)

image-20230318150353403

描述了浏览器和操作系统的版本。

最早期的浏览器只支持文本,后来浏览器支持图片,再后来支持视频、音频、js…

浏览器开发者针对不同阶段的浏览器做了不同的版本,通过判定请求的User-Agent

现在的 User-Agent 主要用来区分 PC 和移动端

Referer

当前页面的"来源"

如果直接通过地址栏输入地址或者直接点击 收藏夹,都是没有 referer 的。

广告商在很多平台上都投放了广告。广告是按照点击计费的,用户点击广告,此时就会跳转到广告主所在的页面上,同时广告商就要给广告平台发钱。

广告被点击了多少次,次数如何衡量?如何统计?

平台可以统计,广告商自己也能统计。

平台这边有个计费服务器,每次点击都打到计费服务器上,记录日志。

广告商也有日志,广告商投放广告可能投放了很多平台,记录有哪些是百度的 referer,哪些是360的 referer,哪些是搜狗的 referer…

HTTP 本身是明文传输的,很容易获取到请求内容,也有办法篡改内容。

有可能本来是来自搜狗的请求,referer 被改成是别人的?

“运营商劫持”(非正常情况)

Cookie

本质上是浏览器给网页本地存储数据的机制。

网页,默认是不允许访问计算机的硬盘的(保证安全)。

cookie, 浏览器对于访问硬盘做出了明确的限制。

cookie, 是通过键值对的方式存储数据的。

image-20230318153646851

  • Cookie 从哪里来?

Cookie 的数据是来自于服务器的,服务器会通过 http 响应的报头部分(Set-Cookie 字段)

服务器来决定 浏览器的 Cookie 要存什么。

  • Cookie 在哪里存的?

可以认为是存在浏览器中的,本质上是存在硬盘的。

不同的浏览器,各自存各自的 Cookie。同一个浏览器不同的域名,对应不同的 Cookie。

Cookie 里的内容不光是键值对,还有过期时间。比如有些网站,登陆一次后,自动记录登录状态。

  • Cookie 要到哪里去?

回到服务器。

客户端通过 Cookie 记录当前用户使用中间状态,当用户访问浏览器的时候,就自动把 Cookie 内容带到请求里,服务器就能知道现在客户端是啥样子的。

举个栗子:

我想配个电脑(台式机),在淘宝上和客服反复拉扯。

1.先跟客服说我的需求,客服说 ok,然后 客服没动静了

2.过了一会儿,我又发消息说你在吗。

(客服同一时间是要和很多人服务的,客服看到后第一反应是先往上翻一翻聊天记录,看看我找他是要干啥,这个聊天记录就相当于 cookie,表示客户端当前的状态)

Cookie 就好像是 服务器在浏览器这边搞的一个寄存处一样。

Cookie 可能是用来保存登录状态的,也可能用来存别的。浏览器保存账号密码是别的功能,和 http 关联不大。

  • 过期时间有啥用?

有些公共电脑(比如打印店的电脑),登录自己的账号,此时登录状态就保存在 Cookie 中了,下次使用的时候 很可能 Cookie 就过期了,就要重新登录了。

认识请求 “正文” (body)

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

1.application/x-www-form-urlencoded

2.multipart/form-data

3.application/json

HTTP 响应

image-20230318162526372

四个部分

1.首行

image-20230318162354911

2.header

3.空行

表示 header 的结束标记

4.body

认识 “状态码” (status code)

描述了这次响应 的结果(成功?失败?原因是啥?)

image-20230318163154215

200 OK 成功了

404 Not Found 要访问的资源不存在,在服务器上没找着。

image-20230318163441786

403 Forbidden 访问被拒绝,没有权限访问

302 Move temporarily 重定向 (类似于呼叫转移)

这样的响应报文中,会在 header 中有个 Location 属性,通过这个属性描述要跳转到哪个新的网址。

image-20230318164830847

image-20230318165020771

500 服务器内部错误(服务器代码抛异常)

504 Gateway Timeout(响应时间太久,浏览器等不及了)

gateway 网关,一个网络的入口/出口,通常也代指一个机房的入口服务器。

状态码分成几个大类:

image-20230318165743111

HTTP 协议中有些是可以自定义的:

1.URL 中的路径

2.URL 中的 query string

3.header 中的键值对

4.header 中 cookie 键值对

5.body

HTTP 协议报文格式总结

image-20230318190622300

如何构造 http 请求

对于 GET 请求:

1.地址栏直接输入

2.点击收藏夹

3.html 中的 link, script, img, a…

4.form 标签(通过代码构造)

通过 form 表单构造 HTTP 请求

<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metahttp-equiv="X-UA-Compatible"content="IE=edge"><metaname="viewport"content="width=device-width, initial-scale=1.0"><title>Document</title></head><body><!-- 表单标签,允许用户和服务器之间交互数据--><!-- 要求提交的数据以键值对的结构来组织--><formaction="https://www.sogou.com"method="post"><inputtype="text"name="studentName"><!-- input type="submit" 构造了一个特殊的提交按钮, value 属性描述了按钮中的文本--><!-- 点击这个按钮就会触发 form 表单的"提交操作", 也就是构造 http 请求发给服务器--><inputtype="submit"value="提交"></form></body></html>

image-20230318191523446

image-20230318193051768

image-20230318193424095

对于 form 构造的 POST 请求来说,body 里的数据格式和 query string 是非常相似的,也是键值对结构,键值对之间用 & 分割,键和值之间用 = 分割。

form 标签只能构造 GET 和 POST 请求,无法构造 PUT, DELETE, OPTIONS 等方法的请求。

通过 ajax 构造 HTTP 请求

另外还有一种,功能更强的构造 http 请求的方式,ajax.

Ajax 即Asynchronous Javascript And XML(异步 JavaScript 和 XML).

ajax, 也是浏览器提供的一种,通过 js 构造 http 请求的方式。

同步:A 始终盯着 B,A 负责关注B 啥时候就绪

异步:A 不盯着 B,B 就绪之后主动通知 A

html 中,通过 ajax 发起 http 请求,就属于"异步"的方式。

这一行代码执行"发送请求"操作之后,不必等待服务器响应回来,就可以立即先往下执行。当服务器的响应回来之后,再由浏览器通知到我们代码当中。

  • 代码中如何使用 ajax?
  1. js 原生提供 ajax 的 api , 但是原生的 api 特别难用。
  2. jquery 提供的 ajax, api 针对原生 api 的封装,简单很多。
$.ajax();//只有一个参数,是一个 js 对象(大括号表示的键值对)

jquery 中,$ 是一个特殊的全局变量,jquery 的 api 都是以 $ 的方法的形式引出来的。

<script>
        $.ajax({type:'get',url:'https://www.sogou.com?studentName=zhangsan',//此处 success 就声明了一个回调函数,就会在服务器响应回到浏览器的时候触发该回调//正是此处的回调,体现了"异步"success:function(data){//data 则是响应的正文部分
            console.log("服务器响应回到浏览器之后, 浏览器触发该回调, 通知到我们的代码当中");}});
    console.log("浏览器继续往下执行后续代码");</script>

注意 : 该代码直接执行,只是能看到构造的请求,不能获取到正确的响应。因为发送请求给搜狗这个服务器,服务器没有处理请求。

image-20230308204715851

后面我们自己能写服务器了之后,就可以给自己的服务器发送请求,自然就可以处理了。

js 本身是不能直接控制操作系统的线程(不像 Java),但是浏览器在 实现 ajax 的时候在内部使用了多线程。js 直观上看没有多线程,实际上还是涉及到的。

ajax 和 form 相比:ajax 功能更强

1.支持 put, delete 等方法,而 form 只有 get , post

2.ajax 发送的 请求可以灵活设置 header

3.ajax 发送的请求的 body 也是可以灵活设置的。

测试免不了要构造 http 请求,写代码构造吗?

还有更为方便的构造 http 请求的方式,使用第三方工具 postman

postman 是个有对象的软件,postwoman(功能和 postman差不多)

1.先注册登录

2.创建 workplace

3.新建一个标签页

image-20230308212749685

除了上面的手动构造之外,postman 还有一个功能,可以生成构造请求的代码,方便我们在自己的程序中集成。

image-20230308213157502

抢票相当于 是 线程竞争信号量

标签: http 网络 服务器

本文转载自: https://blog.csdn.net/qq_63983125/article/details/129641813
版权归原作者 银河罐头 所有, 如有侵权,请联系我们删除。

“HTTP 协议”的评论:

还没有评论