HTTP/HTTPS协议

news2025/1/8 22:11:35

什么是HTTP协议

HTTP被称为超文本传输协议(里面不仅仅可以是字符串,还可以是图片,特殊字符等),这是一种应用非常广泛的应用层协议. HTTP协议诞生于1991年,现在是最主流使用的一种应用层协议.它从诞生到现在为止迭代了多个版本.

但目前最主流使用的还是HTTP1.1和HTTP2.0. HTTP协议是基于传输层的TCP协议来实现的(1.0, 1.1, 2.0都是基于TCP实现的, 而3.0则是基于UDP来实现的).

想我们平常打开一个网站,就是来通过HTTP协议来传输数据的. 像我们在游览器中输入百度的网址,游览器就会给百度的服务器发送有一个HTTP请求,百度服务器就会返回一个HTTP响应. 这个响应被解析后就会变成我们看到的网页内容.(这个过程中可能有多次HTTP请求)(HTTP协议的交互过程,就是经典的一问一答)

HTTP格式

了解HTTP格式,我们可以使用一个抓包工具,抓包工具本质上就是一个代理程序,可以获取到网络上传输的数据,显示出来,从而给程序猿一些参考.这里我们使用fiddler.打开fiddler,我们可以抓包到很多数据包,因为电脑上有很多程序在默默做很多事情. 

这里我们打开一个网站,其实浏览器和服务器之间HTTP交互不止一次,也是有很多次.第一次交互拿到的是这个页面的html,html需要依赖css和js,图片的等.等html被游览器加载后,又会触发到一些其他的http请求,获取到css,js等.......

这里我们搜索搜狗的网页.观察fiddler窗口.蓝色的表示返回的就是一个html. 

上面的窗口就是请求的明细,下面的窗口就是响应的明细.

点击raw就可以查看到http请求的原始数据:

http响应的原始数据:

这样显示是因为这个响应数据被压缩了.

HTTP请求格式

这里HTTP请求包含4部分:

1.首行

这里也由三个部分组成,由空格来分割.

2. 请求头(header)

从第二行开始到后面都是请求头,这里类似于TCP报头中的重要的属性一样. 是由文本方式来组成的.报头中包含了很多的键值对,每个键值对都占一行,键和值之间用:分割.这里的减值有什么含义都是HTTP协议来规定的.

3. 空行

请求头后面会有一个空行,这个表示结束标志.

4. 正文(body)

这是http的载荷部分,有的http有载荷,有的没有.

HTTP响应格式

1. 首行

2. 响应头

这里也是用减值对来表示的.每个键值对为一行.

3. 空行

4. 正文(body)

这里响应的载荷是html

HTTP请求

认识URL

url是一个很重要的概念. 它是描述一个网络上的资源位置.像搜狗的: https://www.sogou.com/ 就是一个最简单的url.

上述就是有一个完整的url.这里通过ip地址知道服务器在哪里,通过端口号知道程序是哪个,通过路径知道是访问哪个资源.

https: 协议名称.这个可以是有其他类型的

user.pass: 登入信息. 这个现在已经不会使用了,一般都被省略

服务器地址: 这里是域名,也可以是ip地址.

端口号: 端口号表示你要访问服务器哪个端口.如果没有,游览器会自动给一个默认的端口号.这里的端口用啥为默认值,取决于协议.

文件路径: 这里可能是一个真实的硬件文件也可能是一个虚拟文件.

查询字符串: 针对请求的内容进行补充. 它是客户端给服务器传递信息的重要途径.它是键值对结构,用&分割键值对,用 = 来分割键和值,这里的键值对内容都是程序员自定义的.

片段标识符: 主要用于页面内的跳转.

关于URL encode

像一些特殊字符 / ? 等被url当做特殊意义来理解,这些字符在url中就不能随意出现. 如果需要使用某个特殊字符,就需要先对特殊字符进行转义.且中文字符在url中也需要转义,因为中文字符是由utf-8或者GBK的编码方式构成的,它们其中的某个字节可能也会被当做特殊字符.

转义规则就是: 将需要编码的字符转为16进制,从右往左,取4位,每两位为一位,前面加上%,编码成%xy的格式.

认识方法

这里最常用的就是GET和POST方法. GET就是从服务器中拿一个东西过来(读操作),POST就是往服务器中放一个东西过去(写方式). 这些语义虽然是官方文档中的注释,但是在实际开发中,开发者可能不会按这一套来.可能POST可以是读操作,GET是写操作.

一般我们从游览器中输入url,这时游览器就会发送一个GET请求.我们可以通过fiddler来观察.这里我们以https://www.sogou.com为例:

这里我们就可以看到方法是GET.而GET请求有一些特点:

1.url的query string(用于补充信息) 可以为空,也可以不为空

2. header部分有多个键值对

3. body部分为空

而POST方法则多用于登录和上传的场景.这里以我登录一个QQ为例:

一般来说,GET通常是没有body,POST通常有body.GET习惯把需要的补充信息放到query string中(url中),而POST会把这些信息放到body中.

POST的特点:
1. psot在第一行

2. url的query string一般为空

3. header部分有多个键值对

4. body部分一般不为空.

POST和GET的区别(面试题)

这两者在本质上其实都没有区别.因为使用GET的场景可以使用POST.使用POST的场景也可以使用GET.这里区别于代码是怎么使用的. 

但是在使用习惯上是有区别的:

1. GET习惯于把数据放到url中的query string, POST习惯于把数据放到body中.

2. 在标准文档中的语义get是用来获取数据.post是用来给服务器传输数据的.

3. 关于幂等性. 标准文档中,建议GET请求实现为幂等的,POST则无要求.

4.GET请求是可以被收藏夹受藏的.但POST请求不可以.

认识报头(header)

Host

它表示服务器的地址和端口号. 

Content-Length与Content-Type

它,们表示body中的数据长度和body中的数据格式. 这两个键值对和body密切想相关,要是数据包没有body,他们就不会存在.

可以通过Content-Length来处理粘包问题. HTTP底层是基于TCP,也是连续传多个HTTP数据报,在接受方的接收缓冲区中也会积累多个包的数据.应用程序就可以通过这个Content-Length来明确包与包之间的边界.

而body可以传输很多种格式,程序猿都可以自己约定格式.Content-Type就是记录body的数据格式. 一般请求中的格式有:

application/json: body就是json格式

application/x-www-form-urlencoded: 通过html中的form标签构造出来的一种格式. 特点可以认为是把query string放到body里了.

multipart/form-data: 上传文件时使用的.

响应的格式有:

test/plain 纯文本

test/html html

test/css css

application/javascript js

.......

User - Agent(UA)

这里我们可以发现UA是有操作系统信息和游览器信息组成的. 在以前游览器和游览器之间有不能的效果,有的可以显示图片,有的不可以等等差异,服务器就可以通过UA信息来判定,你的设备老就不返回新特性,是新设备就返回新特性. 且它还有一个作用就是判定系统是PC系统还是移动端系统. 根据这个信息来返回不同的页面布局.

Referer

描述当前这个页面从哪里来.也就是它的父路径.

通过它就可以来知道哪些请求是通过谁的广告引流过来的.

Cookie

它的本质就是一个游览器这边本地持久存储数据的机制. 游览器作为电脑的程序可以直接读取本地文件.但是游览器上的网页是不能通过游览器提供的api来读写本地文件,因为游览器没有给网页提供这样的api. 但是游览器给网页提供了一个可以有限度的存储数据,但不能随意访问文件系统的api. 这里最经典的就是Cookie这样的存储机制.

请求中的Cooke字段就是把本地存储的Cookie信息发送到服务器那边.而响应中会有一个set-Cooke字段,就是服务器告诉游览器你要在本地保存哪些信息. 这就像去医院看病. 去到一个新的科室,就是客户端给服务器发送新的请求. 每次刷就诊卡,就是在使用Cooker中的信息,让服务器来对客户端有一个清晰的认识.而就诊卡就是客户端中的持久化存储数据的机制.

cooke的重要结论:

Cooke是服务器返回给浏览器的.通常都是首次访问后.

Cookie会存储到浏览器本地主机硬盘上,后序每次访问服务器都会带上Cooker.不同的客户端,保存的Cookie是不同的.即使使用同一个主机,使用不同的浏览器,Cooker大概率也不同.

Cookie中都是键值对格式的数据,都是程序猿自定义的.

Cookie在硬盘上保存,是按照不同的域名为维度来存储的.游览器访问百度,有一组cookie.访问搜狗,有一组cookie.

Cookie的用途是用来在客户端存储数据.最主要的就是存储用户的身份标识,服务器就可以通过标识来区分用户了.(其他的业务数据一般不会放到cookie中.cookie是可以随时删除的. 把业务数据放到服务器中,通过cookie中的身份标识来找到对应的数据; 且账号密码一般也不会放到cookie中, 游览器有另一个保存机制来保存密码)

状态码

状态码一般是用于响应当中的.表示响应的结果如何?HTTP中的状态码是标准约定好的.

这里我们介绍几个常用的状态码.

1. 200 OK: 表示成功访问

2. 404 Not Found: 表示访问的资源没有找到.

3. 405 Method Not Allowed: 表示服务器只支持GET请求,但是你发送的是POST.

4. 403 Forbidden: 请求的资源没有访问权限.

5. 500 Internal Server Error: 服务器内部错误,也就是服务器挂了

6. 504 Gateway Timeeout: 访问服务器超时,可能是服务器挂了,也可能是网挂了

7. 302 Move temporarily: 重定向(临时重定向). 类似与访问的是A,但是A告诉你,去找B,游览器就会去找B.

8. 301 永久重定向: 这里就是游览器会将重定向的结果记录下来,下次再去访问,就会直接访问重定向的目标地址.不必多跳转一次.

构造HTTP请求

通过PostMan

可以下载PostMan来直接来这个第三方库中生成HTTP请求.

 通过代码构造

public class HttpClient {
    private Socket socket;
    private String ip;
    private int port;
    public HttpClient(String ip, int port) throws IOException {
    this.ip = ip;
    this.port = port;
    socket = new Socket(ip, port);
    }
    public String get(String url) throws IOException {
    StringBuilder request = new StringBuilder();
    // 构造⾸⾏
    request.append("GET " + url + " HTTP/1.1\n");
    // 构造 header
    request.append("Host: " + ip + ":" + port + "\n");
    // 构造 空⾏
    request.append("\n");
    // 发送数据
    OutputStream outputStream = socket.getOutputStream();
    outputStream.write(request.toString().getBytes());
    // 读取响应数据
    InputStream inputStream = socket.getInputStream();
    byte[] buffer = new byte[1024 * 1024];
    int n = inputStream.read(buffer);
    return new String(buffer, 0, n, "utf-8");
    }
    public String post(String url, String body) throws IOException {
    StringBuilder request = new StringBuilder();
    // 构造⾸⾏
    request.append("POST " + url + " HTTP/1.1\n");
    // 构造 header
    request.append("Host: " + ip + ":" + port + "\n");
    request.append("Content-Length: " + body.getBytes().length + "\n");
    request.append("Content-Type: text/plain\n");
    // 构造 空⾏
    request.append("\n");
    // 构造 body
    request.append(body);
    // 发送数据
    OutputStream outputStream = socket.getOutputStream();
    outputStream.write(request.toString().getBytes());
    // 读取响应数据
    InputStream inputStream = socket.getInputStream();
    byte[] buffer = new byte[1024 * 1024];
    int n = inputStream.read(buffer);
    return new String(buffer, 0, n, "utf-8");
    }
    public static void main(String[] args) throws IOException {
    HttpClient httpClient = new HttpClient("42.192.83.143", 8080);
    String getResp = httpClient.get("/AjaxMockServer/info");
    System.out.println(getResp);
    String postResp = httpClient.post("/AjaxMockServer/info", "this is body"
    System.out.println(postResp);
    }
}

什么是HTTPS

HTTPS它就是HTTP的改进版,是在HTTP协议的基础上引入了一个加密层SSL.引入的原因就是运营商的劫持事件.如果是明文传输,它就可以在路由器中修改服务器返回的响应.而HTTPS就是通过加密来进一步的保证用户的信息安全.

HTTPS加密

这里的加密分为两种: 对称加密和非对称加密

对称加密:

它就是通过同一个密钥来把明文变成密文,也可以通过它把密文变成明文.

非对称加密:

它有两个密钥,公钥用来加密,私钥用来解密.

这时,服务端就可以在本地生成对称密钥,通过公钥(在第一次客户端请求,客户端就会叫服务器将公钥发送给它,这个就算给别人获取到了也并无大碍)来加密对称密钥,发送给服务器. 服务器就可以通过私钥来解密得到对称密钥.则接下来客户端和服务器的信息都可以通过对称密钥来加密和解密了.

中间人攻击

上面那种方法看似安全,其实还有很大的安全隐患,也是所谓的中间人攻击.服务器可以创建出一对公钥和私钥,黑客也可以用相同的方式来创建出一对公钥和私钥,冒充自己是服务器.

解决方法

这里的解决方式就是引入一个"证书". 客户端可以要求服务器提供一个证书.

这个证书是一个结构化的数据,里面包含了很多属性,最后用字符串的形式提供.

证书中会有一系列信息:

服务器的域名,公钥,证书有效期........

证书是搭建服务器的人从第三方的公证机构进行申请的.

这样客户端就不是需要拿非对称秘钥中的公钥了,也是要证书.

而对于证书中的公钥,黑客是不能进行修改的.因为客户端拿到证书后会进行检验真伪.证书里会有一个"签名",也就是校验和(这个校验和被公证机构那种自己的私钥进行了加密). 这个校验和就是使用一系列的算法把证书中的其他字段进行计算得到一个较短的字符串. 

而客户端拿到证书后会做两件事:

1. 按照同样的校验和算法,把证书的其他字段都重新计算一边,得到校验和1.

2. 使用系统中内置的公证机构的公钥,进行签名解密,得到校验和2.

要是这两个校验和相同,则就是证书没有被修改,要是不相同就是被修改了.

注意:

1)这里如果黑客直接修改公钥,不修改签名. 算出的校验和肯定不一样.

2)如果修改公钥也重新生成签名,由于黑客不知道公证机构的私钥,就无法重新加密签名.要是它拿自己的私钥加密,客户端那边的公证机构的公钥就会解密失败.

 到这里,安全系数就得到了极大的提高.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1471882.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

图像处理ASIC设计方法 笔记3 跨时钟域处理思想

P43第二章 数据路径并行策略 全并行、全串行、半并行 P47 第三章 时序问题和解决方法 锁存器的时序分析,工具做不到,需要设计者手工分析 存储器中SRAM可以直接做到ASIC里面(CMOS工艺)而DRAM不行 P55 作者是不是把sensor翻译成 成像器 成像器向ASIC输入被处理数据 片外…

【ECharts】调用接口获取后端数据的四种方法

使用eacharts做大屏,需要使用后端数据,下面的方法是自己试过有效的,有什么不对的,望各位大佬指点。 目录 方法一:在mounted中使用定时器调用eacharts方法(定时器可以获取到data中的数据) 方法…

MySQL的SQL语句

1.MySQL连接 连接命令一般是这样写的 mysql -h$ip -P$port -u$user -p比如:mysql -h127.0.0.1 -P3306 -uroot -p -h 指定连接的主机地址;-P 指定连接端口号;-u 指定用户名 -p指定用户名密码 2.SQL分类 DDL(Data Definition Language) 数据定义语言&…

STM32F103学习笔记(六) RTC实时时钟(应用篇)

目录 1. RTC 实时时钟的应用场景 2. RTC 的配置与初始化 2.1 设置 RTC 时钟源 2.2 初始化 RTC 寄存器 2.3 中断配置 2.4 备份寄存器配置 2.5 校准 RTC 3. 实例演示代码 4. 总结 1. RTC 实时时钟的应用场景 实时时钟(RTC)在嵌入式系统中具有广泛…

(二十三)Flask之高频面试点

目录: 每篇前言:Q1:为什么把request和session放在一起?Q2:Local对象的作用?Q3::LocalStack对象的作用?Q4:一个运行中的Flask应用程序分别包括几个Local/LocalStack&#…

msvcr110.dll找不到怎么修复?多种解决msvcr110.dll缺失方法分析

面对如“程序无法启动,因为电脑中缺失msvcr110.dll”这样的错误提示时,你的日常工作或游戏娱乐很可能会被迫暂停。这种问题在Windows用户中相当普遍,它们来源于某些共享的系统文件缺失。不过,好消息是解决此类错误通常并非困难任务…

springboot集成quartz定时任务并接入后台管理系统(copy即用)

说明:项目启动后会根据设置的时间进行执行,业务代码根据自己的需求更改,数据库文件在最后(记得清空数据库哦~)这里需要注意的一点就是className字段表示的是下面的对应的DynamicTask的路径如:com.example.demo.quartz.task.DynamicTask,如有多个定时任务copy并更改Dynam…

Oracle ADG相关介绍

文章目录 一、ADG原理1、ADG介绍2、ADG搭建流程 二、ADG相关参数三、增量修复 一、ADG原理 1、ADG介绍 Oracle ADG(Advanced Data Guard)是Oracle数据库的一项高可用和灾难恢复技术,它通过将数据保持在物理备库中来提供数据保护和容灾能力。…

FariyGUI × Cocos Creator 3.x 弹窗制作

在fgui里制作一个弹窗 新建一个按钮,作为返回按钮 新建一个标签 做成这个样子 其中包含两个节点,名称分别为title和closeButton 可以阅读fgui的源码window.js得到,closeButton按钮只需要输入名称即可在contentPane设置时自动绑定。 且会…

Wagtail安装运行并结合内网穿透实现公网访问本地网站界面

文章目录 前言1. 安装并运行Wagtail1.1 创建并激活虚拟环境 2. 安装cpolar内网穿透工具3. 实现Wagtail公网访问4. 固定的Wagtail公网地址 正文开始前给大家推荐个网站,前些天发现了一个巨牛的 人工智能学习网站, 通俗易懂,风趣幽默&#xf…

nginx高级配置详解

目录 一、网页的状态页 1、状态页的基本配置 2、搭配验证模块使用 3、结合白名单使用 二、nginx 第三方模块 1、echo模块 1.1 编译安装echo模块 1.2 配置echo模块 三、nginx变量 1、内置变量 2、自定义变量 四、自定义图标 五、自定义访问日志 1、自定义日志格式…

Java根据excel模版导出Excel(easyexcel、poi)——含项目测试例子拿来即用

Java根据excel模版导出Excel(easyexcel、poi)——含项目测试例子拿来即用 1. 前言1.1 关于Excel的一般导出2.2 关于easyexcel的根据模版导出 2. 先看效果2.1 模版2.2 效果 3. 代码实现(核心代码)3.1 项目代码结构3.2 静态填充例子…

数学建模【GM(1, 1)灰色预测】

一、GM(1, 1)灰色预测简介 乍一看,这个名字好奇怪,其实是有含义的 G:Grey(灰色)M:Model(模型)(1, 1):只含有一个变量的一阶微分方程模型 提到灰色,就得先说…

【已解决】解决Win11忘记开机密码(不用重装系统)

问题起因 因为在实验室的电脑从过年就没有用过,也不知道为什么记性这么差,就把电脑密码忘了,但是又不想用系统盘重装电脑。于是从网上整理一些文章,最后写了下面一篇解决方法 解决方法 1.首先在登录界面(输入密码那…

深入探索 JS 的提升机制、函数与块作用域以及函数表达式和声明(下)

🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 🍚 蓝桥云课签约作者、上架课程《Vue.js 和 E…

合并3D线条模型怎样进行调整长度---模大狮模型网

在3D建模软件中合并3D线条模型后,要调整线条的长度可以通过以下步骤进行: 选择线条模型:首先,在3D建模软件中选择您要调整长度的线条模型。这通常涉及使用选择工具或者鼠标点击线条模型来进行选择。 使用拉伸工具:大多…

采访影视行业艺术指导“Sora入局,或将改变游戏规则?”

自OpenAI发布Sora已经过去了半个月,人们对于这个新兴的“文生视频”(text-to-video)大模型工具都已经有了初步的认识,经过半个月的沉淀,他们也陆续发布了一些更加令人震惊的demo,话不多说,我们先…

大厂性能测试监控指标及分析调优指南

一、哪些因素会成为系统的瓶颈 CPU:如果存在大量的计算,他们会长时间不间断的占用CPU资源,导致其他资源无法争夺到CPU而响应缓慢,从而带来系统性能问题,例如频繁的FullGC,以及多线程造成的上下文频繁的切换…

Jqgrid入门

最近要用Jqgrid做项目,之前都没怎么接触过,看了看官网有一个小demo,于是下下来后,发现这个demo有点问题,度娘了一下,发现有的博主直接贴官网的代码,截了个图,我真是***,还…

【Java程序设计】【C00313】基于Springboot的物业管理系统(有论文)

基于Springboot的物业管理系统(有论文) 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的物业管理系统,本系统有管理员、物业、业主以及维修员四种角色权限; 管理员进入主页面,主要功能包…