http-简单的http 协议


前言

http 协议的特点

一、http 协议特点

支持客户/服务器模式

在这里插入图片描述
由(只能由)客户端向服务器发出请求,服务器端响应请求,并进行相应的服务;
服务器端如果没有接收到请求,是不会向客户端发出响应的。

简单,快速

  1. 请求方法少,常用的有GET,HEAD,POST等。每种方法规定了客户与服务器联系的类型不同
  2. HTTP 协议简单,所以,HTTP 服务器的程序规模小,通信快

灵活

  1. http允许传输任意类型的数据对象
  2. 使用Content-Type 来标记传输的类型。
    参考
    https://www.runoob.com/http/http-content-type.html
    查看Content-type

无连接

无连接强调的是http 的特性;
特点:限制每次连接只处理一个请求

http 协议的长连接和短连接,实质上是TCP 协议的长连接和短连接
实现方式:
短连接;由客户端发起
长连接;TCP长连接的保活功能主要为服务器应用提供

短连接

短连接可以理解成是http 连接的实现,
服务器处理完用户的请求,并收到客户的应答后,就会断开连接

优点:

  • 节省传输时间,实现简单

长连接

当HTTP协议头部中字段Connection:keep-alive表示支持长链接。
优点:

  • 长连接专门解决效率问题。当建立好了一个连接之后,可以多次请求。

缺点:

  • 容易造成占用资源不释放的问题。

有效性,有效性,没断开,可以使用长连接;

无状态

HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。
换句话说,就是每次连接,都要把需要的信息都携带上,不记录之前的信息;
如果携带的信息大,那么处理起来,就慢;如果携带的信息少,那么处理起来就快。

为了解决无状态的问题,使用

  • Cookie
  • Session

来解决

二、URL与URI的区别与联系

三、报文结构分析

通用报文头

首部字段名说明
Cache-Control控制缓存的行为
Connection逐跳首部、连接的管理
Date创建报文的日期时间
Pragma报文指令
Trailer报文末端的首部一览
Transfer-Encoding指定报文主题的传输编码方式
Upgrade升级为其他协议
Vim代理服务器的相关信息
Warning错误通知

Connection

Connection:keep-alive 当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接

Connection:close 代表-个Request完成后,客户端和服务器之间用于传输HTTP数据的TCP连接会关闭,当客户端再次发送Request,需要重新建立TCP连接

请求报文头

首部字段名说明
Accept用户代理可处理的媒体类型
Accept-Charset优先的字符集
Accept-Encoding优先的内容编码
Acccpt-Language优先的语言(自然语言)
AuthorizationWcb认证信息
Expeet期待服务器的特定行为
From用户的电子邮箱地址
Host请求资源所在服务器
If-Match比较实体标记(ETag)
1f-Modified-Simce比较资源的更新时间
If-None-Mateh比较实体标记(与If-Match相反)
lf-Range资源未更新时发送实体Byte的范围请求
If-Unmodified-Since比较资源的更新时间(与If-Modifed-Since相反)
Max-Forwards最大传输逐跳数
Proxy-Authorization代理服务器要求客户端的认证信息
Range实体的字节范围请求
Referer对请求中 URI的原始获取方
TE传输编码的优先级
User-AgentHTTP客户端程序的信息

User-Agent

作用: 告诉HTTP服务器, 客户湍使用的操作系统和浏览器的名称和版本
很多情况下我们会通过User-Acnet来判断浏览器类型,从而进行不同的兼容设计

响应报文头

首部字段名说明
Accept-Ranges是否接受字节范围请求
Age推算资源创建经过时间
ETag资源的匹配信息
Location令客户端重定向至指定URI
Proxy-Authenticate代理服务器对客户端的认证信息
Retry-After对再次发起请求的时机要求
ServerHTTP服务器的安装信息
Vary代理服务器缓存的管理信息
WWW-Authenticate服务器对客户端的认证信息

实体报文头

首部字段名说明
Allow资源可支持的HTTP方法
Content-Encoding实体主体适用的编码方式
Content-Language实体主体的自然语言
Content-Length实体主体的大小(单位:字节)
Content-Location替代对应资源的URI
Content-MD5实体主体的报文摘要
Content-Range实体主体的位置范围
Content-Type实体主体的媒体类型
Expires实体主体过期的日期时间
Last-Modified资源的最后修改日期时间

Content-type

作用: 说明了报文体内对象的媒体类型

  • text/html:HTML格式
  • text/plain :纯文本格式
  • text/xml:XML格式
  • image/gif:gif图片格式
  • image/jpeg:jpg图片格式
  • image/png:png图片格式

application

  • application/xhtml+xml:XHTML格式
  • application/xml:XML数据格式
  • application/atom+xml: Atm XML聚合格式
  • application/json据格式
  • JSON类application/pdf:pdf格武
  • application/msword:Word文档格式
  • application/octet-stream :二进制流数据(如常见的文件下载)
  • application/x-www-form-urencoded:表单提交

四、发起http请求

发送请求的方法

方法名称方法说明支持的HTTP 协议版本
getGET 方法用于根据 URI 参数从服务器中获取数据,是最常用的请求方法之一1.0、1.1
headHEAD 方法与 GET 方法类似,但服务器在响应时只返回响应行和响应头,不会返回响应体1.0、1.1
postPOST 请求用于将数据发送到服务器。例如使用 HTML 表单上传文件或提交客户信息等1.0、1.1
putPUT 方法可以向服务器中写入文档,有点类似于使用 FTP 上传文件1.0、1.1
deleteDELETE 方法用于删除 URI 所指定的目标资源,与 PUT 方法正好相反1.0、1.1
connectCONNECT 方法要求在与代理服务器通信时建立隧道,实现用隧道协议进行 TCP 通信1.1
optionsOPTIONS 方法用来查询目标资源所在服务器支持的 HTTP 方法1.1
traceTRACE 方法可以让服务器端将收到的请求返回给客户端,主要用于开发阶段的测试和诊断1.1
link建立和资源之间的联系1.0
unlink断开链接关系1.0

http 状态码

  • 1xx:指示信息-表示请求已接收,继续处理;这类响应是临时响应
  • 2xx:成功-表示请求已被成功接收
  • 3xx:重定向-要完成请求必须进行更进一步的操作
  • 4xx:客户端错误-请求有语法错误或请求无法实现
  • 5xx:服务器错误-服务器未能实现合法的请求
    比如:
  • 200 OK:客户端请求成功
  • 202 Accepted 已接受,但是未处理成功
  • 206 Partial Content:客户发送了一个带有Range头的GET请求,服务器完成了它
  • 301 Moved Permanently:所请求的页面已经转移至新的url;永久移动。浏览器会自动定向到新的URI.
  • 302 Found:所请求的页面已经临时转移至新的url
  • 304 Not Modified:客户端有缓冲的文档并发出了一个条件性的请求,服务器告诉客户原来缓冲的文档还可以继续使用
  • 400 Bad Request:客户端请求有语法错误,不能被服务器所理解
  • 401 Unauthorized:请求未经授权,这个状态代码必须和WW-Authenticate报头域一起使用
  • 403 Forbidden:对被请求页面的访问被禁止
  • 404 Not Found:请求资源不存在
  • 500 Internal Server Error:服务器发生不可预期的错误原来缓冲的文档还可以继续使用
  • 502 Bad Gateway 充当网关或代理的服务器,从远端服务器接收到了一个无效的请求
  • 503 Server Unavailable:请求未完成,服务器临时过载或当机,一段时间后可能恢复正常

get 和post 的区别

其实get 和post 没有本质的差别;
两者只是请求方法不一样;
get 请求浏览器里面带不了请求体;在nodejs 里面可以携带请求体。
post 请求在浏览器里面可以带请求体
所以在浏览器中,get 和post 的区别:

  • GET 通过url 传递参数,POST 可以通过url 和request body 传递参数;
  • GET 传递的参数上限是2k;POST 没有限制
  • GET在浏览器回退时是无害的,而POST会再次提交请求
  • GET产生的URL地址可以被收藏,而POST不可以
  • GET请求会被浏览器主动缓存,而POST不会,除非手动设置
  • GET请求只能进行url编码,而POST支持多种编码方式
  • GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留
  • GET请求在URL中传送的参数是有长度限制的,而POST没有限制
  • 对参数的数据类型,GET只接受ASCII字符,而POST没有限制
  • GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息

post 两次请求

当发送post时,有时候,有发现有options请求;有options 一共有两种情况:
当请求头是application/json 的形式的时候:
1.跨域;
2. 自定义请求头的时候也会发送;
当发送跨域的POST请求时,浏览器会先发送一次OPTIONS请求,这是因为浏览器的同源策略。OPTIONS请求被称为预检请求(pre-flightrequest),它是CORS(跨源资源共享)机制中的一部分。
预检请求的目的是为了确保实际请求(例如POST、PUT等)对目标服务器是安全的。在实际请求之前,浏览器向服务器发送一个预检请求,询问服务器是否允许跨域请求以及允许哪些HTTP方法、头部字段等。服务器通过响应头信息告诉浏览器它支持哪些方法和头部字段。
OPTIONS请求会包含以下头部信息:
0zigin’:表示请求来源的域名
表示实际请求将使用的HTTP方法。Access-Control-Request-Method: 表示实际请求将携带哪些自定义头部字段。Access-Control-Request-Headers:
服务器需要在响应头中返回一些CORS相关的信息,例如:
表示哪些域名可以进行跨域访问Access-Control-Allow-0rigin
表示允许哪些HTTP方法。Access-Control-Allow-Methods:
表示允许哪些头部字段。Access-Control-Allow-Headers`:
如果服务器允许当前请求的跨域访问,那么浏览器才会发起实际的POST请求。否则,浏览器将阻止请求,并在控制台报告错误。

五、解决无状态

Cookie

  • cookie 保存在客户端;客户端请求服务器,如果服务器需要记录用户的状态,就会返回一段文本信息给客户端浏览器。浏览器接收到信息后,就会保存起来。在下次请求的时候,浏览器把请求的信息连同服务器发送过来的cookie一起传送给服务器。服务器通过解析cookie 来辨认用户的状态。

  • 不能跨域。两个网址只要域名,端口都相同,就可以共享cookie。不要求协议相同。

  • cookie 大小有限制,大多数浏览器最大支持4096字节。最大支持300个,主流浏览器FirFox :50个,Opera:30个。如果超出了个数显示,浏览器会随机清除cookie,给新cookie腾位置。

  • 明文保存,不适合保存重要或者涉及隐私的内容

  • 只能存储String 类型的对象

  • 有过期时间,一旦过期,浏览器会自动删除

在这里插入图片描述
可以在控制台打出

console.log(document.cookie)

查看此网站的cookie
查看cookie 是否可用

console.log(window.navigator.cookieEnabled);//true

在这里插入图片描述

cookie 的格式

Set-Cookie: “name=value;domain=.domain.com;path=/;expires=Sat, 05 Jun 2024 13:29:01 GMT;HttpOnly;secure”
name:一个唯一确定的cookie名称。通常来讲cookie的名称是不区分大小写的。
value:存储在cookie中的字符串值。最好为cookie的name和value进行url编码
domain:cookie对于哪个域是有效的。所有向该域发送的请求中都会包含这个cookie信息。这个值可以包含子域(如:yq.aliyun.com),也可以不包含它(如:.aliyun.com,则对于aliyun.com的所有子域都有效).
path: 表示这个cookie影响到的路径,浏览器跟会根据这项配置,像指定域中匹配的路径发送cookie。
expires:失效时间,表示cookie何时应该被删除的时间戳(也就是,何时应该停止向服务器发送这个cookie)。如果不设置这个时间戳,浏览器会在页面关闭时即将删除所有cookie;不过也可以自己设置删除时间。这个值是GMT时间格式,如果客户端和服务器端时间不一致,使用expires就会存在偏差。
max-age:  Cookie 失效的时间,单位秒,默认为 -1。如果为正数,则该 Cookie 在 maxAge 秒后失效。如果为负数,该 Cookie 为临时 cookie ,关闭浏览器即失效,浏览器也不会以任何形式保存该 cookie 。如果为 0,表示删除该 Cookie 。与expires作用相同,用来告诉浏览器此cookie多久过期(单位是秒),而不是一个固定的时间点。正常情况下,max-age的优先级高于expires。
HttpOnly: 告知浏览器不允许通过脚本document.cookie去更改这个值,同样这个值在document.cookie中也不可见。但在http请求张仍然会携带这个cookie。注意这个值虽然在脚本中不可获取,但仍然在浏览器安装目录中以文件形式存在。这项设置通常在服务器端设置。如果给某个 Cookie 设置了HttpOnly属性,则无法通过 JS 脚本 读取到该Cookie 的信息,但还是能通过 Application 中手动修改 Cookie,所以只是在一定程度上可以防止 XSS 攻击,不是绝对的安全。
secure: 安全标志 设置Cookie是否使用安全协议传输。安全协议有 HTTPS,SSL等,在网络上传输数据之前先将数据加密。默认为false。当 secure 值为 true 时,Cookie 在 HTTP 中是无效,在 HTTPS 中才有效。

Application 修改在这里插入图片描述利用cookide 可以做自动登录,保存浏览历史,身份验证等功能。

js 处理cookie

// 读取cookie
function getCookie(name) {
    var arr, reg = new RegExp("(^| )" + name + "=([^;]*)(;|$)");
    if (arr = document.cookie.match(reg))
      return (arr[2]);
    else
      return null;
  }
  
 // 设置cookie
 /*
 name:cookie 名
 value: cookie 值
 expiredays: 有效时间
 */
function setCookie (name, value, expiredays) {
    var exdate = new Date();
    exdate.setDate(exdate.getDate() + expiredays);
    document.cookie = name+ "=" + escape(value) + ((expiredays == null) ? "" : ";expires=" + exdate.toGMTString());
  };
  // 单个设置 
  //document.cookie='name=123;expires=Thu, 25 Nov 2024 12:31:23 GMT'
 // 删除cookie
function delCookie (name) {
    var exp = new Date();
    exp.setTime(exp.getTime() - 1);
    var cval = getCookie(name);
    if (cval != null)
     document.cookie = name + "=" + cval + ";expires=" + exp.toGMTString();
  };

服务端nodejs
设置cookie

var http = require('http');
var fs = require('fs');
 
http.createServer(function(req, res) {
    res.setHeader('status', '200 OK');
    res.setHeader('Set-Cookie', 'uid=123456;domain=.xxx.com;path=/;max-age=1000');
    res.write('Hello World');
    res.end();
}).listen(8888);
 
console.log('running localhost:8002')

服务器解析cookie

因为客户端传过来的cookie 值会有重复项,所以只取第一个匹配的即可。

var parse = function(cstr) {
    if (!cstr) {
        return null;
    }
 
    var dec = decodeURIComponent;
    var cookies = {};
    var parts = cstr.split(/\s*;\s*/g);
    parts.forEach(function(p){
        var pos = p.indexOf('=');
        // name 与value存入cookie之前,必须经过编码
        var name = pos > -1 ? dec(p.substr(0, pos)) : p;
        var val = pos > -1 ? dec(p.substr(pos + 1)) : null;
        //只需要拿到最匹配的那个
        if (!cookies.hasOwnProperty(name)) {
            cookies[name] = val;
        }/* else if (!cookies[name] instanceof Array) {
            cookies[name] = [cookies[name]].push(val);
        } else {
            cookies[name].push(val);
        }*/
    });
 
    return cookies;
}

cookie 的认证流程

在这里插入图片描述

在这里插入图片描述

nodejs使用第三方插件测试写入
/*
 * @Author: 
 * @Date: 2024-02-02 18:40:28
 * @LastEditors: 
 * @LastEditTime: 2024-02-05 16:01:01
 * @FilePath: \vite-vue3-electron\server\index.js
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
const express=require('express');
const app =express();
const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser')


//设置跨域访问
app.all('*', function(req, res, next) {
   res.header("Access-Control-Allow-Origin", "*");
   res.header("Access-Control-Allow-Headers", "X-Requested-With");
   res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
   res.header("X-Powered-By",' 3.2.1');
   res.header("Content-Type", "application/json;charset=utf-8");
   next();
});

app.use(bodyParser.urlencoded({ extended: false }))// 解析字符
app.use(bodyParser.json())
app.use(cookieParser('aabbccdd'))

var questions=[
{
data:213,
num:444,
age:12
},
{
data:456,
num:678,
age:13
}];

  
    app.get('/getData',function(req,res){
        console.log("req",req)
        // res.status(200),
        // res.json(questions)
        let response={
            status:200,
            data:questions

        }
        res.send(response);

    });
    app.post('/postData',(req,res)=>{
        console.log(req.body);//获取前端ajax提交的数据
        res.send({
            code:200,
            data:req.body
        })
    })

    // 设置cookie
app.get('/cookie',(req,res)=>{
    // 使用了中间件后就可以访问req和res上的cookies对象
	console.log(req.cookies);
    // 不加密写入cookie
    // res.cookie('num', 10, {
	// 	// domain: 'xxx.com',
	// 	// path: '/',
	// 	maxAge: 24 * 3600 * 1000
	// })

	// 加密后读取cookie
    console.log(req.signedCookies['num'])
    res.cookie('num', 10, {
		// httpOnly: true,
		// secure: true,
		signed: true,// 签名一定要写上这个,表示对cookie 进行前民
		maxAge: 24 * 3600 * 1000
	})
	res.send({
        code:200,
        data:'ok'
    });

})

    //配置服务端口
    var server = app.listen(8001, function () {

    var host = server.address().address;

     var port = server.address().port;

        console.log('Example app listening at http://%s:%s', host, port);
    })

如果cookie 不加签名的话

在这里插入图片描述
在这里插入图片描述
如果加了签名
在这里插入图片描述
在这里插入图片描述

cookie 的优缺点

优点
优点备注
扩展性强,简单易用是一个文本信息,键值对的方式保存
可用性高客户端,服务器端都能使用
占用内存少存储在客户端,不会给服务器端造成数据压力
具有持久性通过设置max-age;可以在客户端上保存长达数年的时间;轻松保存用户的信息。即使服务端崩溃,cookie 的值夜不会收到影响
具有透明性可以在Application 上清晰的看到cookie
缺点
缺点 备注
明文暴露问题很容易被用户看到,并窃取
安全性问题在application,明文暴露
大小数量限制大小4096字节,数量一般是50个
禁用限制浏览器使用无痕模式,禁用cookie 存储
跨域问题只能是ip,端口都相同才能共用cookie
使用场景
  1. 用户登录状态
  2. 用户信息存储
  3. 跟踪用户行为
  4. 广告定位
  5. 用户行为偏好
  6. 缓存数据,用户历史和浏览数据
使用场景举例

前提:. 服务端返回的cookie 不需要客户端去关心。下面的session 有图示证明这个说法。所以客户端只需要关心自己设置的cookie 值就好。
cookie 失效:

  1. cookie未设置持久化,浏览器关闭,那么cookie 就会立刻失效。
  2. 服务端修改cookie 信息,另cookie 值失效。

用户7天免登录

// 保存用户信息
function setCookie(name,pwd,cookieName) {
    let userName = name // 用户名
    let passWord = pwd //密码
    let cookieName = cookieName // cookie名称
    let data = {
        username: userName,
        password: passWord
    }
    let d = new Date()
    let saveTime = 7// cookie保存时间(单位:天)
    d.setDate(d.getDate() + saveTime)
    document.cookie = cookieName + '=' + JSON.stringify(data) + ';path=/;expires=' + d.toGMTString()
}

// 验证cookie 是否失效
function getCookie(cookieName) {
    let cookie = document.cookie
    let cookieName = cookieName // cookie名称
    let arr = cookie.split('; ') // 将cookie信息和时间戳拆分为数组
    let userInfo = null
    for (let i = 0; i < arr.length; i++) {
        let tempArr = arr[i].split('=') // 将cookie名称和data拆分开,分别是数组的第一个元素和第二个元素
        if (tempArr[0] === cookieName) {
            userInfo = JSON.parse(tempArr[1])
        }
    }
    if (userInfo) {
        // cookie存在,直接登录
        console.log(userInfo)
    } else {
        // 因为cookie不存在,所以不做任何处理
    }
}

Session

session 是记录客户端状态的字段,保存在服务器上。

特点说明
基于cookie 实现,由服务器实现,且存储在服务器端不会暴露给客户端,客户端只能拿到Session id
易用性可以存储任意类型的数据
独立性,会话隔离每个客户端与服务器之间建立联系的时候,都有唯一的session ID
临时性有过期时间
状态保持将信息存储在session 中,可以获取用户的信息状态
可灵活配置可以存放多种信息,如用户登录状态

nodejs 设置session

/*
 * @Author: @@@ 1094549944@qq.com
 * @Date: 2024-02-02 18:40:28
 * @LastEditors: @@@ 1094549944@qq.com
 * @LastEditTime: 2024-02-05 16:29:47
 * @FilePath: \vite-vue3-electron\server\index.js
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
const express=require('express');
const app =express();
const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser')
var session = require('express-session');

//设置跨域访问
app.all('*', function(req, res, next) {
   res.header("Access-Control-Allow-Origin", "*");
   res.header("Access-Control-Allow-Headers", "X-Requested-With");
   res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
   res.header("X-Powered-By",' 3.2.1');
   res.header("Content-Type", "application/json;charset=utf-8");
   next();
});

app.use(bodyParser.urlencoded({ extended: false }))// 解析字符
app.use(bodyParser.json())
app.use(cookieParser('aabbccdd'))

app.use(session({
    name: 'session_name', // 这里是cookie的name,默认是connect.sid
    secret: 'aaabbbccc', // 建议使用 128 个字符的随机字符串
    resave: true,
    saveUninitialized: false,
    cookie: { maxAge: 60 * 1000, httpOnly: true }
}));


var questions=[
{
data:213,
num:444,
age:12
},
{
data:456,
num:678,
age:13
}];

  
    app.get('/getData',function(req,res){
        console.log("req",req)
        // res.status(200),
        // res.json(questions)
        let response={
            status:200,
            data:questions

        }
        res.send(response);

    });
    app.post('/postData',(req,res)=>{
        console.log(req.body);//获取前端ajax提交的数据
        res.send({
            code:200,
            data:req.body
        })
    })

    // 设置cookie
    app.get('/cookie',(req,res)=>{
        // 使用了中间件后就可以访问req和res上的cookies对象
        console.log(req.cookies);
        // 不加密写入cookie
        // res.cookie('num', 10, {
        // 	// domain: 'xxx.com',
        // 	// path: '/',
        // 	maxAge: 24 * 3600 * 1000
        // })

        // 加密后读取cookie
        console.log(req.signedCookies['num'])
        res.cookie('num', 10, {
            // httpOnly: true,
            // secure: true,
            signed: true,// 签名一定要写上这个,表示对cookie 进行前民
            maxAge: 24 * 3600 * 1000
        })
        res.send({
            code:200,
            data:'ok'
        });

    })
    // 设置session 
    app.get('/session',(req,res)=>{
        console.log(req.cookies);
        console.log("req.session.sessionNum || req.cookies.sessionNum",req.session.sessionNum || req.cookies.sessionNum)
        if(req.session.sessionNum || req.cookies.sessionNum) {
            res.send({
                code:200,
                data:'ok'
            });
        } else {
            req.session.sessionNum = 1;
            res.cookie('sessionNum', 1, { maxAge: 60 * 1000, singed: true});
            res.send({
                code:200,
                data:'first'
            });
        }
    })

    //配置服务端口
    var server = app.listen(8001, function () {

    var host = server.address().address;

     var port = server.address().port;

        console.log('Example app listening at http://%s:%s', host, port);
    })

在这里插入图片描述
在这里插入图片描述

第二次访问
在这里插入图片描述
在这里插入图片描述

此时浏览器请求
第一次,在返回头有set-cookie
在这里插入图片描述
第二次请求 在请求头,携带cookie
在这里插入图片描述

session 认证流程

在这里插入图片描述
注意:不管是session 还是cookie, 都不需要客户端做什么。都是服务端的操作。

保存Session ID 的方式

  1. Cookie
  2. URL 重写
  3. 隐藏表单
URL 重写

如果浏览器禁止cookie,比如说,浏览器在无痕模式下运行,是禁止写入cookie 的,可以采用url 重写的方式,直接在url上写入sessionId
方式有两种

  1. http://www.baidu.com;sessionId=1234567123131xxx
  2. http://www.baidu.com?sessionId=1234567123131xxx

两者没有区别,只是在解析中,处理方式有所区别。第一种可以把sessionid 和其他的params 区分开

Session 超时失效

Session的有效期
Session超时失效
程序调用HttpSession.invalidate()
服务器进程被停止

session 的优缺点

优点说明
比Cookie 安全一点
可以存储任意类型的数据
支持集群部署
具有唯一性
相较于JWT,具有自动清除机制服务器会有session 回收机制,可以自动删除过期的Session
兼容性好
缺点说明
过度依赖Cookie如果用户禁用cookie,那么就会非常影响用户体验
占用服务器资源存储在服务器端
生命周期问题session过期问题;解决办法:使用定时器刷新session,或者将session 的过期时间设置的更长一些,确保session 不会过早失效
分布式问题解决办法:1. 从存储角度:使用集中式session 存储方案,比如使用redis等缓存中间件来缓存session 信息;2. 使用Nginx;。以 Nginx 为例,可以配置 ip_hash 来实现 可以让相同 IP 的请求在负载均衡时都打到同一台机器上
安全问题解决办法:可以使用加密技术;比如使用https协议

总结

本篇文章表格主要参考 慕课网的《大话HTTP协议 漫画+图解打造的编程基础课程》
参考文档:
https://blog.csdn.net/qq_41895003/article/details/130448214
https://blog.csdn.net/qq_41895003/article/details/130455766

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jxy9998

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值