【javaWeb】HTTP协议

HTTP (全称为 “超文本传输协议”) 是一种应用非常广泛的应用层协议

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

image-20231127164617632

上图是通过Fiddler对访问百度搜索页时抓取的一个http协议的包。

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

http请求

HTTP 请求可以认为是分成四个部分

  1. 首行
  2. 请求头(header)
  3. 空行
  4. 正文(body)

首行

首行包含三部分,三部分之间用空格来区分。

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

就以上面访问百度的首行来介绍

  • 版本号:GET
  • URL(俗称网址):https://www.baidu.com/:
  • 版本号:HTTP/1.1

认识 URL

  • URL :唯一资源定位符,标识互联网上的唯一的资源的位置。
    • 资源在哪,在哪个服务器的哪个目录下的哪个文件。互联网上的具体地址。
  • URI :唯一资源标识符,身份标识,为了和别的资源区分开。
    • 实际上,URL 也可以起到身份标识的效果。URL 也可以视为是一个 URI。

实际开发中,经常就把URL和URI这俩词就混用了.

URL 基本格式:协议名称://ip:端口号/路径?查询字符串

image-20231127164634264

tcp,ip,udp 协议格式都是 rfc 系列文档定义的。URL不是 http 专属的.很多协议都可以使用 URL。

其中登录信息(认证)这一部分现在已经不用了。

URL 最关键的四个部分:

  1. 域名/IP
  2. 端口号
  3. 带层次的路径
  4. 查询字符串

假设你要去图书馆结束去查询图书:

邯院东图书馆二楼:10号图书馆机器人/查询图书?书名=明解C语言第3版&作者=柴田望洋&出版社=人民邮电出版社

其中,ip地址是邯院东图书馆二楼,端口号是10号图书馆机器人,带层次的查询路径是查询图书,查询字符串(以键值对的方式来组织的):书名=明解C语言第3版&作者=柴田望洋&出版社=人民邮电出版社

以百度首页的ip地址为例https://www.baidu.com/,一个 url 这里的这几个部分,有些是可以省略的。

可以省略端口:省略端口的时候,浏览器会提供默认端口.对于 http 来说,默认端口 80;。对于 https 来说,默认端口是 443。

路径其实没有省略:/也是路径,只是有点短代表"根目录"。是 HTTP 服务器的根目录。HTTP 服务器是系统上的一个进程。就委托这个服务器管理系统上的一个特定的目录。这个目录里的资源都可以让外面进行访问。/ 管理的根目录,可以是系统上的任意一个目录。(http 服务器具体的配置)

查询字符串可以进行省略。

认识URL encode(转义字符):像 中文 或者 / ? : 等这样的字符, 已经被url当做特殊意义理解了. 因此这些字符不能随意出现.

假如我们在百度首页搜索c++:https://www.baidu.com/s?wd=c%2B%2B。在查询字符串(query string)中包含c%2B%2B,%2B就是URL encode

urldecode就是urlencode的逆过程。

认识 “方法” (method)

image-20231127164747729

方法描述了这次请求的语义(想干啥)。实际开发中,这里的方法大部分都是用不到的。最常见的就是两个:**GET,POST。**其中POST的使用频率要大于GET。

此处看到的 HTTP 的方法的语义,是 HTTP 设计者美好初心。但是实际上,开发的时候,语义仅供参考。

GET 请求的典型场景:

  1. 在浏览器地址栏里直接输入 url
  2. html 里的 link, script, img, a…
  3. 通过js 来构造 get

POST请求的典型场景:

  1. 登录跳转
  2. 上传文件

面试题:GET和POST的典型区别

GET 和 POST 没有本质区别(在大部分场景下,彼此之间都能相互替代)。但是在使用习惯上,还是有差异的。

  1. 语义上的差别:GET 请求一般是用于从服务获取数据。POST一般是用于给服务器提交数据
  2. 信息传递差别:
    1. POST 传递消息是通过 body。
    2. GET 传递的信息一般都是放在查询字符串(query string)中
  3. 设计上的差别:(幂等:相同的输入,得到的结果也是确定的。反之结果不确定就是不幂等的)
    1. GET 通常会被设计成幂等的.
    2. POST 不要求幂等
  4. 被缓存的差别:(被缓存:把请求的结果保存下来了下次请求就不必真请求了,直接取缓存结果了)
    1. GET 可以被缓存的。
    2. POST 则一般不能被缓存

注意上面的区别只是使用上的区别,在大部分场景下,彼此之间都能相互替代。GET 也不是不能有 body,POST 也不是不能有 query string,只是非常少见而已。完全也可以使用 GET 提交,使用 POST 获取。完全可以把 POST设定成幂等,GET 不幂等。

网上有些说法有待商:

  1. GET 请求传输的数据存在上限,比如上限的版本

实际上 rfc 标准文档中,对于 HTTP GET 请求的长度上限明确说没有规定的。有些上古时期的浏览器/服务器,实现的时候,搞了个限制。

  1. POST 比 GET 更安全

依据就是,如果是使用 GET 请求进行登录,此时用户名密码通过 querystring 来传递。就会出现在浏览器地址栏中,就一眼就被别人看到了。但是安全指的是,如果黑客窃取到你的数据,你的敏感信息不会泄露,安全核心要素是加密。

请求报头(header)

下列部分就是 header 这里是一堆键值对。

image-20231127164811968

每一行,是一个键值对。键和值之间使用 : 分割。这些键值对都是 HTTP 事先定义好的,有特定的含义的。

host

大概描述了服务器所在的 地址和 端口。Host 这里的 地址和端口,用来描述你最终要访问目标。这个内容大概率和 URL 中是一样的,也有一定的情况下是不同的。比如借助代理想要去访问一个网址,URL只代理的的地址和端口,host则只最终的地址和端口。

Content-Type和Content-Length

  • Content-Type:表示 body 中的数据长度
  • Content-Length:表示请求的 body 中的数据格式.

如果是 GET 请求,没 body, 请求中没有这俩字段。如果是 POST 请求,有 body,则必须要有这俩字段。

Content-Type 取值是非常多的:text/html text/css image/png image/jpg application/javascript application/json

User-Agent (简称 UA)

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

最早期浏览器,只支持文本,后来浏览器支持图片,后来支持视频,音频,js。网站开发者,开发的时候做的这个网页,是否要带图片,是否要带视频,是否要带js。为了解决这个问题,开发者做了很多版本,然后通过判定请求的 user agent来决定返回什么版本。

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

Referer

Referer:表示当前页面的"来源"。如果直接通过地址栏输入地址,直接点击收藏夹… 都是没有 referer。

通过网站点击广告的时候,点击次数,网站进行统计统计,广告主自己也进行统计。广告主通过点击次数来给网站钱。广告主广告投放的网站不止一家,用Referer来区分时从哪一个网站点进来的。

http响应HTTP 本身明文传输,很容易获取到请求内容,也有办法篡改内容。本来是来自于A网站的请求,referer 被改成了B网站了,广告商统计的通过B网站点击进来的次数就会多了,就会多付给B网站钱了。这种情况就是运营商劫持(抢钱)。为了预防这种情况吧http请求换成https请求。

cookie

  • Cookic是什么?

非常重要的 header 属性。本质上是 浏览器 给网页提供的 持久化存储数据 的机制。为了保证安全,网页默认是不允许访问你计算机的硬盘的。cookie 对于浏览器访问硬盘做出了明确的限制。cookie 就是通过键值对的方式来组织数据的。

  • Cookie 是从哪来的?
    • Cookie 中的数据是来自于服务器的。
    • 服务器来决定 浏览器的 Cookie 要存什么。
    • 服务器会通过 HTTP 响应的 报头部分 (Set-Cookie 字段),返回给浏览器,浏览器来存储Cookie
  • Cookie 是在哪存的?
    • 存在于浏览器所在主机的硬盘中.
    • Cookie 在存储的时候,是按照 浏览器 + 域名 维度来进行细分的
      • 不同的浏览器,各自存各自的 cookie
      • 同一个浏览器不同的域名,对应不同的 cookie
    • cookie 里的内容不光是键值对,同时还有 过期时间。比如,有很多网站,登录一次之后,自动记录登录状态。
  • Cookie 要到哪里去?
    • 回到服务器这里
    • 客户端同一时刻是有很多的。客户端这边就会通过 Cookie 来保存当前用户使用中间状态。当客户端访问浏览器的时候, 就会自动的把 Cookie 的内容带入到请求中。服务器就能够知道现在客户端是啥样子了。相当于在和淘宝客服询问的时候,过一段时间再问一条消息,客服通过聊天记记录就能知道要干什么了,聊天记录表示了 客户端 的状态,相当于 cookie。

当浏览器保存好 cookie之后,后续再给服务器发送请求的时候,header就会自动带上这样的 cookie。cookie 就像是 服务器 在浏览器这边搞的个寄存处一样。

过期时间是有啥用?

有些公共的电脑(学校图书馆电子阅览室)在公共电脑上,登录的自己的账号。此时登录状态就保存到 cookie 中了

下个人使用的时候,很可能 cookie 就过期了,就要求重新登录了。越敏感的网站,过期时间就越短。

Cookie和Session关联和区别

关联在登录功能中没需要配合使用:

image-20231127164828347

区别:

  • 存储机制的区别
    • Cookie 是客户端的存储机制.
    • Session 是服务器的存储机制
  • 存储内容的区别
    • Cookie 里面可以存各种键值对(还可以存别的)
    • Session 则专门用来保存用户的身份信息.
  • 使用上的区别
    • Cookie 完全可以单独使用, 不搭配 session (实现非 登陆 场景下)
    • Session 也可以不搭配 Cookie 使用, Cookie 跟浏览器强相关的。
      • 手机 app 登陆服务器,服务器也需要 Session, 此时就没有Cookie 的概念
  • 和HTTP协议的关系
    • Cookie 是属于 HTTP 协议中的一个部分
    • Session 则可以和 HTTP 无关(TCP,websocket … 也可以用 session)

请求 “正文” (body)

正文中的内容格式和 header 中的 Content-Type 密切相关。post的body这里存放的数据 的内容和格式 都是程序猿自主定义的

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

http响应

下面是一个登录请求的相应报文

image-20231127164849496

HTTP 相应可以认为是分成四个部分

  1. 首行(HTTP/1.1 200 0K)
  2. 请求头(header)
  3. 空行(表示 header 的结束标记)
  4. 正文(body)

HTTP/1.1 200 0K分别表示:版本号 状态码 状态码描述

状态码

常见状态码:

200 OK:成功了

404 Not Found:访问的资源不存在,在服务器上没找到

403 Forbidden 访问被拒绝(没有权限) 302 Move temporarily 重定向 500 服务器内部错误(服务器代码抛异常了)

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

状态码可以分为以下几类:

2** 成功

3**重定向

4**客户端错误

5**服务器错误

请求转发和请求重定向

  • 重定向,可以重定向到外部资源的(跳转到别的网站)
  • 请求转发,只能该服务器内部的资源之间转发,少了一次交互更高效

https协议

HTTPS = HTTP + 安全层(SSL/TLS).

SSL是用来加密的协议,主要是为了防止运营商劫持。SSL是较早提出的安全协议,而TLS是SSL的继任者.

网络上如果明文传输数据,是非常危险的。就需要加密才能保证安全。

HTTPS 其实主要是涉及到其中的 SSL 部分。SSL 并非仅仅是在 HTTPS 中使用。密码学这个事情,本身非常复杂,对于数学(数论) 要求是非常高的。

对称加密

对称加密介绍

进行安全传输核心就是加密,其中一种最简单有效的办法,叫做"对称加密"。

对称加密:同一个密钥(key),既可以用来加密,也可以用解密。

加密过程:a(明文) + key => b(密文)

解密过程:b(密文) + key => a(明文)

image-20231127164907075

引入对称加密之后, 即使数据被截获, 由于黑客不知道密钥是啥, 因此就无法进行解密, 也就不知道请求的

真实内容是啥了。

对称加密的缺点

对称加密的安全性的前提是:密钥不能被黑客知道。

对称秘钥是由客户端产生的。假设客户端生成一个密钥,客户端就需要把密钥告知服务器。

image-20231127164925138

客户端生成密钥,发给服务器。此时由于密钥刚刚生成,服务器还不知道。此处的密钥只能明文传输,密钥可能就被黑客给截获了。

解决以上问题关键在于,需要想办法安全的把秘钥传递过去。

非对称加密

要想解决对称加密的问题,我们此处就引入了非对称加密的概念。

非对称加密介绍

生成了一堆秘钥:公钥和私钥

使用公钥加密:明文 + 公钥 => 密文

使用私钥解密:密文 + 私钥 => 明文

反过来使用公钥解密,使用私钥加密也可以。

A 要给 B 一些重要的文件, 但是 B 可能不在. 于是 A 和 B 提前做出约定:

B 说: 我桌子上有个盒子, 然后我给你一把锁, 你把文件放盒子里用锁锁上, 然后我回头拿着钥匙来开锁取文件.

在这个场景中, 这把锁就相当于公钥, 钥匙就是私钥. 公钥给谁都行(不怕泄露), 但是私钥只有 B 自己持有. 持有私钥的人才能解密

image-20231127164939876

此时客户端的公钥从服务器拿,黑客也能知道公钥。但是黑客不知道私钥,私钥是服务器自己才有的。客户端使用公钥,来对对称密钥进行加密,传输给服务器。服务器就可以拿着自己的私钥来解密得到对称密钥,此时客户端服务器就可以使用这个对称密钥进行后续传输了。

对称加密比非对称加密要快,为了尽可能的提高整体的速度,后续传输使用对称加密。

中间人攻击

上面只说了如何使用公钥进行加密,没说如何获取公钥。我么获取公钥的时候如果直接传输公钥也是会出现安全问题。

image-20231127164952929

客户端不知道pub2是否是真正的公钥,客户端将自己的对称密钥key加密传输。

黑客截取加密传输的信息,使用自己的私钥pri2进行解密。获取到了对称密钥key。黑客继续使用服务器的pub1公钥对key重新加密,继续传给服务器。

服务器使用pri1来解密接收到的数据,得到对称密钥key。服务器以为这个对称密钥就是从客户端过来的。后续交互都是用这个对称密钥进行加密。

中间人攻击会导致对称密钥被获取。解决中间人攻击的关键,在于让客户端能够辨别,当前这个响应(公钥)是服务器真实的公钥。

证书

证书就是为了解决中间人攻击而引入的。本质上是引入第三方的公证机构。

服务器(网站)在设立之初,就需要去专门的认证机构,申请证书(提供一些资质的)。审核通过,就会给你颁发证书。服务器生成的公钥,也就包含在这个证书中了。客户端向服务器请求公钥的时候,此时就不是请求单单一个公钥,而是把整个证书都请求过来。客户端拿到证书之后,就可以对证书进行校验(验证一下,证书是不是假的,是不是被篡改的)。如果发现证书是无效,浏览器就会直接弹框告警(有的莫名其妙的小网站,可能会有这种情况)。

客户端拿到证书的过程:

image-20231127165002892

客户端拿到证书,就可以对证书进行校验(不牵扯和服务器的交互)。证书上面会带有一个特定的字段,叫做证书的签名。

image-20231127165021320

证书的签名是一个被加密的字符串。客户端可以使用认证机构提供的公钥进行解密。解密之后,得到的结果相当于是一个 hash1值。

客户端就可以使用同样的hash算法,针对其他字段再算一次hash值,得到 hash2。看看 hash1(从签名中解出来的)和 hash2(客户端自己算的)这俩值相同,说明证书是有效的(没有被算改过的)

image-20231127165039902

注意:这里对证书签名解密和加密的公钥和私钥,不是客户端和服务器传输对称密钥的私钥,而是认证机构提供的。

认证机构提供的公钥在客户端的操作系统或者操作系统中的。私钥是申请证书的时候, 证书发布机构给服务器的。

上述过程证书的签名保证了非对称密钥的公钥不被篡改,避免了中间人攻击。公钥对对称加密的秘钥进行加密,避免了对称加密密钥被截获。然后在http协议交互的过程中通过对称加密的方式就能安全的传输数据了。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode(33)最小覆盖子串【滑动窗口】【困难】

目录 1.题目2.答案3.提交结果截图 链接: 76. 最小覆盖子串 1.题目 给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 "" 。 注意: 对于 t 中重复字…

Java数据结构之优先级队列(PriorityQueue)

1、概念 队列:是一种FIFO(First-In-First-Out)先进先出的数据结构,对应于生活中的排队的场景, 排在前面的人总是先通过,依次进行。 优先队列:是特殊的队列,从“优先”一词&#xff…

C# 实现微信退款及对帐

目录 需求 基础准备 关键代码 操作界面 ​编辑 退款订单类及方法 退款功能实现 对帐 支付商家后台相关要点 实时交易帐单查询 精确交易帐单查询 小结 需求 在招聘报名系统里,考务费支付是其中一个环节,支付方式很多种,比如银联、…

GitHub----使用记录

一、上传文件到仓库 1、首先新建一个github仓库 然后先记住这一句指令 2、下载git工具 https://git-scm.com/downloads 下载工具安装不用运行 3、使用git工具上传文件并推送 找到你想上传的文件的位置,右击git Bush here git init :初始化这个仓…

【项目实战】SpringBoot连接openGauss

一:Docker安装openGauss 1.下载openGauss 安装好Docker好以后,执行如下命令下载openGauss3.0镜像。docker pull enmotech/opengauss:3.0.0 2.运行openGauss 执行如下命令docker run -itd --name opengauss \ --restartalways \ --privilegedtrue \ …

OpenAi Q* (Q Star)项目入门介绍

为初学者解释 Open Ai 的 Q*(Q Star) Q* 的两个可能来源。 1)Q 可能是指 "Q-learning",这是一种用于强化学习的机器学习算法。 Q 名称的由来*:把 "Q*"想象成超级智能机器人的昵称。 Q 的意思是这个机器人非常善于做决定。 它从经验中学习,就像你从玩…

什么是数据填报?

数据填报是报表用以满足用户提出的灵活报送数据的需求,能快速开发各类数据采集系统的专业功能。多源填报模型,可实现数据的多源抽取与多源回填,在同一张填报表上实现数据提交至多个不同的数据表、数据库。 随着业务快速变化和扩大&#xff0c…

邮件群发:避免垃圾邮箱,提升营销效果

群发邮件为什么会进入垃圾邮箱呢?常见的原因有:邮件内容出现问题、域名和IP的信誉度不高、退订数或投诉过多等原因。所以,营销人员在做EDM的时候,应该把握方式技巧,才能获取良好的营销效果,避免邮件成为垃圾…

特征可视化,代码详解

输入 输出 代码 import os import torch import torchvision as tv import torchvision.transforms as transforms import torch.nn as nn import torch.optim as optim import argparse import skimage.data import skimage.io import skimage.transform import numpy as np…

15:00面试,15:06就出来了,问的问题有点变态。。。

从小厂出来,没想到在另一家公司又寄了。 到这家公司开始上班,加班是每天必不可少的,看在钱给的比较多的份上,就不太计较了。没想到8月一纸通知,所有人不准加班,加班费不仅没有了,薪资还要降40%…

C++值常用集合算法

C值常用集合算法 set_intersection #include<iostream> using namespace std; #include<vector> #include<numeric> #include<algorithm>class MyPrint { public:void operator()(int val){cout << val<<" ";} };void test() {v…

EC 404 information economics

EC 404 information economics WeChat: zh6-86