HTTP 协议

Posted 银河罐头

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HTTP 协议相关的知识,希望对你有一定的参考价值。

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

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

目录

HTTP 是什么

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

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

目前主要使用的是 HTTP1.1

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

  • sogou.com (网址,URL)

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

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

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

抓包工具的使用

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

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

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

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

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

代理

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

举个栗子:

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

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

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

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

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

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

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

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

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

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

HTTP请求:

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

压缩是什么原理?

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

HTTP响应:

这个文本数据,就是搜狗首页,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

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

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

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

url 最关键的 4 个 部分:

1.域名

2.端口号

3.带层次的文件路径

4.查询字符串

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

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

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

urlencode 编码

urldecode 解码

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

认识 “方法” (method)

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

其中最常见的就是 get , post

GET 请求

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

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

3.通过 js 构造 GET 请求

通过 fiddler 抓包一个 GET 请求:

POST 请求

登录,上传文件

比如我 登录 gitee,

用 fiddler 抓包一个 POST请求

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)

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

  • Host

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

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

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

Content-Type 取值是非常多的。

text/html

text/css

image/png

image/jpg

application/javascript

application/json

User-Agent (简称 UA)

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

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

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

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

Referer

当前页面的"来源"

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

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

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

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

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

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

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

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

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

Cookie

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

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

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

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

  • 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 响应

四个部分

1.首行

2.header

3.空行

表示 header 的结束标记

4.body

认识 “状态码” (status code)

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

200 OK 成功了

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

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

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

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

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

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

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

状态码分成几个大类:

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

1.URL 中的路径

2.URL 中的 query string

3.header 中的键值对

4.header 中 cookie 键值对

5.body

HTTP 协议报文格式总结

如何构造 http 请求

对于 GET 请求:

1.地址栏直接输入

2.点击收藏夹

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

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

通过 form 表单构造 HTTP 请求

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

对于 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>

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

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

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.新建一个标签页

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

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

HTTP协议:协议头是啥东西?

我只是以HTTP举个例子,经常看到说协议的协议头...一般的通信协议都是由哪些协议部分组成的呢?(协议头?协议脚?协议屁股?)
而且协议头一般都是大小不变的还是可变的呢?

请指点

当用户打开一个网页时,浏览器要向网站服务器发送一个HTTP请求头,然后网站服务器根据HTTP请求头的内容生成当次请求的内容发送给浏览器。

当用户设计一个通信协议时,“消息头/消息体”的分割方式是很常用的,消息头告诉对方这个消息是干什么的,消息体告诉对方怎么干。HTTP传输的消息也是这样规定的,每一个HTTP包都分为HTTP头和HTTP体两部分,后者是可选的,而前者是必须的。

扩展资料

HTTP协议常用头部实例

1、Accept:text/html, application/xhtml+xml, application/xml;q=0.9, image/webp, image/apng, */*; q=0.8

作用:向服务器申明客户端(浏览器)可以接受的媒体类型(MIME)的资源

解释:浏览器可以接受 text/html、application/xhtml+xml、application/xml类型,通配符*/* 表示任意类型的数据。并且浏览器按照该顺序进行接收。( text/html —> application/xhtml+xml —> application/xml)

2、Accept-encoding: gzip, deflate, br

作用:向服务器申明客户端(浏览器)接收的编码方法,通常为压缩方法

解释:浏览器支持采用经过 gzip,deflate 或 br 压缩过的资源

参考技术A HTTP(HyperTextTransferProtocol)是超文本传输协议的缩写,它用于传送WWW方式的数据,关于HTTP 协议的详细内容请参 考RFC2616。HTTP协议采用了请求/响应模型。客户端向服务器发送一个请求,请求头包含请求的方法、URI、协议版本、以及包含请求修饰符、客户 信息和内容的类似于MIME的消息结构。服务器以一个状态行作为响应,相应的内容包括消息协议的版本,成功或者错误编码加上包含服务器信息、实体元信息以 及可能的实体内容。

  通常HTTP消息包括客户机向服务器的请求消息和服务器向客户机的响应消息。这两种类型的消息由一个起始行,一个或者多个头域,一个只是头域结束的空行和可 选的消息体组成。HTTP的头域包括通用头,请求头,响应头和实体头四个部分。每个头域由一个域名,冒号(:)和域值三部分组成。域名是大小写无关的,域 值前可以添加任何数量的空格符,头域可以被扩展为多行,在每行开始处,使用至少一个空格或制表符。

  通用头域

  通用头 域包含请求和响应消息都支持的头域,通用头域包含Cache-Control、 Connection、Date、Pragma、Transfer-Encoding、Upgrade、Via。对通用头域的扩展要求通讯双方都支持此扩 展,如果存在不支持的通用头域,一般将会作为实体头域处理。下面简单介绍几个在UPnP消息中使用的通用头域。

  Cache-Control头域

  Cache -Control指定请求和响应遵循的缓存机制。在请求消息或响应消息中设置 Cache-Control并不会修改另一个消息处理过程中的缓存处理过程。请求时的缓存指令包括no-cache、no-store、max-age、 max-stale、min-fresh、only-if-cached,响应消息中的指令包括public、private、no-cache、no- store、no-transform、must-revalidate、proxy-revalidate、max-age。各个消息中的指令含义如 下:

  Public指示响应可被任何缓存区缓存。

  Private指示对于单个用户的整个或部分响应消息,不能被共享缓存处理。这允许服务器仅仅描述当用户的部分响应消息,此响应消息对于其他用户的请求无效。

  no-cache指示请求或响应消息不能缓存

  no-store用于防止重要的信息被无意的发布。在请求消息中发送将使得请求和响应消息都不使用缓存。

  max-age指示客户机可以接收生存期不大于指定时间(以秒为单位)的响应。

  min-fresh指示客户机可以接收响应时间小于当前时间加上指定时间的响应。

  max-stale指示客户机可以接收超出超时期间的响应消息。如果指定max-stale消息的值,那么客户机可以接收超出超时期指定值之内的响应消息。

  Date头域

  Date头域表示消息发送的时间,时间的描述格式由rfc822定义。例如,Date:Mon,31Dec200104:25:57GMT。Date描述的时间表示世界标准时,换算成本地时间,需要知道用户所在的时区。

  Pragma头域

  Pragma头域用来包含实现特定的指令,最常用的是Pragma:no-cache。在HTTP/1.1协议中,它的含义和Cache- Control:no-cache相同。
参考技术B 不变的,协议就和标志一样,告诉你现在你使用的是什么协议,变的只会是后面的 域名本回答被提问者和网友采纳

以上是关于HTTP 协议的主要内容,如果未能解决你的问题,请参考以下文章

Http与Android网络请求的几种协议

网络协议分析 | 应用层:HTTP协议详解HTTP代理服务器

网络基础:HTTP协议 vs HTTPS协议 区别

网络运行原理/网络架构/http协议

[网络]应用层协议:HTTP / HTTPS[转载]

Python网络爬虫——http和https协议