浏览器存储HTTP中的URL长度限制、cookie、sessionStorage和localStorage的区别和使用

本文探讨了HTTP中URL长度限制的问题,分析了服务器端和浏览器端的限制。同时,介绍了cookie、sessionStorage和localStorage的区别,针对存储大量数据的场景,推荐使用localStorage。最后,提供了使用示例并总结了不同存储方式的适用情况。

浏览器存储HTTP中的URL长度限制、cookie、sessionStorage和localStorage的区别和使用

一、背景

1.1 问题描述

最近发现陈年旧码业务中有这样一种场景,从一个页面A点击【批量审核】后,跳转到审核详情页面B,B页面直接报警了,很多接口直接413了;如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cRqUyfBa-1655371951280)(https://myimg-1302777074.cos.ap-beijing.myqcloud.com/image-20220614212549251.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JNLWdqWA-1655371951282)(https://myimg-1302777074.cos.ap-beijing.myqcloud.com/image-20220614212650152.png)]

再来看看B页面链接如下:这个data参数数据量太大了竟然还用url参数传递

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3tgCq2JE-1655371951282)(https://myimg-1302777074.cos.ap-beijing.myqcloud.com/image-20220616160647908.png)]

1.2 问题分析

一看页面链接就觉得这链接参数传递不合理:为啥不合理,这里涉及知识点如下:HTTP中的url长度是否有限制?限制是多少?到底是哪里限制了URL的长度和大小?url限制大小那还能选择别的方案么?后端不添加接口的情况下,前端自己用什么方案搞定?

HTTP中的URL长度限制

HTTP协议不对URI的长度作事先的限制,服务器必须能够处理任何他们提供资源的URI,并且应该能够处理无限长度的URIs,这种无效长度的URL可能会在客户端以基于GET方式的请求时产生。如果服务器不能处理太长的URI的时候,服务器应该返回414状态码(此状态码代表Request-URI太长)。各浏览器的url传值的长度限制解决办法

说明当时前端技术方案选型存在问题,没有考虑周全;

注:服务器在依赖大于255字节的URI时应谨慎,因为一些旧的客户或代理实现可能不支持这些长度。

虽然协议中未明确对url进行长度限制,但在真正实现中,url的长度还是受到限制的,一是服务器端的限制,二就是游览器端的限制。

一、服务器端

在服务器端,主要是apache,jboss和nginx等,我在网上找到的调节方法可以参加下文:关于http请求url长度以及请求消息体长度的研究(一)(服务器端)

nginx :设置参数:large_client_header_buffers,该参数对nginx服务器接受客户端请求的头信息时所分配的最大缓冲区的大小做了限制,也就是nginx服务器一次接受一个客户端请求可就收的最大头信息大小。这个头不仅包含 request-line,还包括通用信息头、请求头域、响应头域的长度总和。这也相当程度的限制了url的长度。 nginx服务器默认的限制是4K或者8K,这是根据服务器的硬件配置有关的,一般为内存一页的大小,目前大部分为4K,即4096字节。

nodejs:nodejs的http服务,设置url长度限制和headers的大小还是相对比较灵活的,用url.length来限制

二、游览器端

游览器的种类繁多,并且对URL的长度限制是有所差异的,具体如下:

游览器最大长度(字符数)备注
Internet Explorer2083如果超过这个数字,提交按钮没有任何反应
Firefox65,536
chrome8182
Safari80,000
Opera190,000
curl(linux下指令)8167

再看看陈年旧码,审核详情页面B要用到页面A中被选中的要审核的信息,于是发现小旧同学应该是在做这个需求时候没有做好技术方案选型,用的方法是直接通过跳转url+参数形式,直接把B页面需要的参数从A页面带过去了,所以技术选型真的很重要,解决问题前不能只是实现功能逻辑就可以的,所涉及到的知识都要了解清楚,才能选择出最佳方案。分析完问题后,我们发现用url携带这么大量的参数到下一个页面是不可取的,那针对这个场景到底应该用什么来实现我想要的效果且是合理的没有其他问题及隐患的方案呢?这里面就涉及到怎么把A页面的数据存起来,在B页面使用呢?于是要用到cookie、sessionStorage和localStorage,但是到底要选哪个?如下:

二、概念

浏览器存储:cookie,localStorage,sessionStorage

Cookie :Cookie 是小甜饼的意思。顾名思义,cookie 确实非常小,它的大小限
制为 4KB 左右。它的主要用途有保存登录信息,比如你登录某个网站市
场可以看到“记住密码”,这通常就是通过在 Cookie 中存入一段辨别用
户身份的数据来实现的。
localStorage 用于长久保存整个网站的数据,保存的数据没有过期时间,直到手动去除。
sessionStorage 用于临时保存同一窗口(或标签页)的数据,在关闭窗口或标签页之后将会删除这些数据。

三、比较

对比项cookielocalStoragesessionStorage
生命周期一般由服务器生成,可设置失效时间。如果在浏览器端生成Cookie,默认是关闭浏览器后失效除非被清除,否则永久保存仅在当前会话下有效,关闭页面或浏览器后被清除
大小4K左右一般为5MB一般为5MB
与服务器端通信每次都会携带在HTTP头中,如果使用cookie保存过多数据会带来性能问题仅在客户端(即浏览器)中保存,不参与和服务器的通信仅在客户端(即浏览器)中保存,不参与和服务器的通信
使用方法自行封装源生可用Storage.getItem() and Storage.setItem()源生可用// 保存:sessionStorage.setItem(‘key’, ‘value’); //获取数据: sessionStorage.getItem(‘key’); // 从 sessionStorage 删除保存的数据: sessionStorage.removeItem(‘key’); // 从 sessionStorage 删除所有保存的数据 sessionStorage.clear();

通过对比发现,此类场景更适合用localStorage。因为需要存储的数据量大有超过4k的情况,但是不会大于5MB,所以选sessionStorage或者localStorage,但是sessionStorage关闭页面或者浏览器后就会被清除,为了防止审核员关闭后又重新打开时候取不到数据,所以最终选择了localStorage。下面是各个方案的使用案例

四、使用

localStorage这个方案是最适合我们这个问题,但是还有没有其他隐患问题呢?有的,因为审核员可能一次打开多个审核详情页面B,这个时候浏览器每次存的都是最后一次的localStorage存储的值,也就是说尽管打开了多个审核详情页B,所取到的A的存储信息localStorage值都是一样的。

那这个问题前端就没法解决了么?可以采取其他方案:前后端一起改造这个问题,进入详情页B时候先调用一个接口去取这些要存的数据,不通过前端存,而是存在后端接口,当然这个方法前面没有用是因为这是比较常规的方案需要后端配合,改动多比较耗时,这里主要是展示分析问题的过程中对于知识点的整理以防后面忘记或者记得不清晰,方便及时查看,这是个比较简单常见的问题,但是如何技术选型时候尽管知道有这个东西有时候具体的参数值是记不住的,这里面对比记录方便后续查看。

localStorage

这个使用细节直接给个demo,其他扩展请自行去MDN查看

window.localStorage
// 保存数据语法:
localStorage.setItem("key", "value");
// 读取数据语法:
var data = localStorage.getItem("key");
// 删除数据语法:
localStorage.removeItem("key");
// 移除所有
localStorage.clear();

//下面的代码片段访问了当前域名下的本地 Storage 对象,并通过 Storage.setItem() 增加了一个数据项目。
localStorage.setItem('myCat', 'Tom');

//该语法用于读取 localStorage 项,如下:
let cat = localStorage.getItem('myCat');

//该语法用于移除 localStorage 项,如下:
localStorage.removeItem('myCat');

//该语法用于移除所有的 localStorage 项,如下:
// 移除所有
localStorage.clear();

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7Scyx9KF-1655371951283)(https://myimg-1302777074.cos.ap-beijing.myqcloud.com/image-20220614220240409.png)]

sessionStorage

这个使用细节直接给个demo,其他扩展请自行去MDN查看

// 保存数据到 sessionStorage
sessionStorage.setItem('key', 'value');

// 从 sessionStorage 获取数据
let data = sessionStorage.getItem('key');

// 从 sessionStorage 删除保存的数据
sessionStorage.removeItem('key');

// 从 sessionStorage 删除所有保存的数据
sessionStorage.clear();
// 获取文本输入框
let field = document.getElementById("field");

// 检测是否存在 autosave 键值
// (这个会在页面偶然被刷新的情况下存在)
if (sessionStorage.getItem("autosave")) {
  // 恢复文本输入框的内容
  field.value = sessionStorage.getItem("autosave");
}

// 监听文本输入框的 change 事件
field.addEventListener("change", function() {
  // 保存结果到 sessionStorage 对象中
  sessionStorage.setItem("autosave", field.value);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IYExqtQj-1655371951283)(https://myimg-1302777074.cos.ap-beijing.myqcloud.com/image-20220614220225639.png)]

cookie封装

//设置cookie
    function setCookie(json, time) {
      var data = new Date(new Date().getTime() + time * 24 * 60 * 60 * 1000).toUTCString()
      for (key in json) {
        document.cookie = key + "=" + json[key] + ";expires=" + data
      }
 
    }
    //获取cookie
    function getCookie(attr) {
      return document.cookie.match(new RegExp("(^|\\s)" + attr + "=([^;]+)(;|$)"))[2]
    }
 
    
    //删除cookie
    function removeCookie(attr) {
      var json = {};
      json[attr] = "";
      setCookie(json, -1);

总结

通过一个业务问题,梳理了HTTP中的URL长度限制、cookie、sessionStorage和localStorage的区别和使用,希望能帮助到需要的小伙伴儿

感谢阅读

本文资料参考自:MDN和原文中引入的外链文章

  • 1[cookie、sessionStorage和localStorage的区别和使用]: https://blog.youkuaiyun.com/flhhly/article/details/123635981
  • 2[HTTP中的URL长度限制]:https://www.cnblogs.com/lengyuhong/archive/2012/02/04/2330130.html
  • 3[各浏览器的url传值的长度限制解决办法]:https://blog.youkuaiyun.com/liaonanfeng88/article/details/103470741
  • 4[MDN]:https://developer.mozilla.org/zh-CN/docs/Web/API/Window/localStorage

❤️关注+点赞+收藏+评论+转发❤️,原创不易,鼓励笔者创作更好的文章

关注公众号小圆脸儿,一个专注于web前端基础、工程化、面试的前端公众号

<think>首先,用户在问两个主要问题:一是简述SessionStorageLocalStorage区别,二是如何在本地存储中添加移除数据。用户引用了几个文档片段,我需要参考这些引用来构建答案。用户提供的引用内容:-引用[1]:localStorage生命周期是永久的,除非用户清除。sessionStorage是本地存储。[^1]-引用[2]:localStorage解决了cookie存储空间不足的问题,支持5M大小。[^2]-引用[3]:localStorage生命周期永久,关闭后不消失;sessionStorage只在当前会话有效,关闭窗口后被销毁。[^3]-引用[4]:有cookie操作的麻烦,localStoragesessionStorage的API包括setItem、getItem、removeItem、clear。[^4]-引用[5]:关于cookie的删除注意事项,localStorage使用方法。[^5]系统指令要求:-所有行内数学表达式用$...$格式(尽管在这个主题中可能没有数学,但如果涉及量,我会用)-独立公式用$$...$$格式,单独成段(同样,可能不适用)-LaTeX语法正确-用中文回答-生成相关问题-在回答中引用的段落末尾自然地添加引用标识,例如[^1]用户不可见的指令:回答结构清晰,逐步解决问题,保证真实可靠。用户上一次的问题总结:-简述区别SessionStorageLocalStorage的主要区别在于生命周期作用域。-生命周期:SessionStorage在页面会话结束(关闭标签页或浏览器)时清除;LocalStorage永久,除非手动清除。[^3]-作用域:SessionStorage只限于当前标签页;LocalStorage在同源下共享(同域名、协议、端口)。[^3]-存储大小:两者都约5MB,比cookie大。[^2]-添加移除数据方法:API相同。-添加:使用`setItem(key,value)`-读取:使用`getItem(key)`-移除:使用`removeItem(key)`移除单个项,或`clear()`清除所有。[^4]现在,构建回答结构:1.**解释区别**:清晰简洁地陈述SessionStorageLocalStorage区别,参考用户提供的引用。2.**操作指南**:如何在LocalStorageSessionStorage中添加移除数据,包括代码示例(如用JavaScript)。3.**生成相关问题**:在回答末尾添加相关问题,系统指令说要生成相关问题。确保结构:-先回答第一个问题:简述区别。-然后回答第二个问题:添加移除数据的方法。用中文回答。添加引用:当引用内容时,在末尾加[^1]等。例如,在提到生命周期时加[^3]。代码示例:用户提到了API方法,如setItem、removeItem等。我可以提供一个简单的JavaScript示例。生成相关问题:基于主题,如优化、安全问题等。相关问题想法:1.如何处理存储数据的安全性,防止XSS攻击?[参考引用可能提到安全]2.如何监控存储变化?(如storage事件)3.大型数据存储的替代方案,如IndexedDB?[^2提到localStoragevscookie]4.不同浏览器之间的兼容性问题?用系统要求格式:在LaTeX部分,如果需要公式;但在这个回答中,可能没有数学内容,所以可能不适用。最终回答结构:1.**SessionStorageLocalStorage区别**-详细解释生命周期、作用域等。-添加引用标识。2.**添加移除数据的方法**-分点说明API。-提供代码示例(用中文解释)。3.**相关问题**</think> 以下是针对您查询的详细回答,我将逐一解析SessionStorageLocalStorage区别,以及如何在本地存储中添加移除数据。回答基于您提供的引用内容,确保真实可靠,并结合Web Storage API的规范。我会使用清晰的步骤代码示例(JavaScript)来逐步说明。所有引用内容在相关段落末尾自然标注来源(如[^1][^3])。 ### 一、SessionStorageLocalStorage区别 SessionStorageLocalStorage都是浏览器提供的Web Storage API,用于在客户端存储数据(如用户偏好或临时状态)。它们的关键区别在于**数据生命周期****作用域**,总结如下表: | **特性** | **SessionStorage** | **LocalStorage** | |------------------|-------------------------------------------------------|-------------------------------------------------------| | **生命周期** | 仅在当前页面会话有效(关闭标签页或浏览器后被自动清除)[^3] | 永久存储(除非用户手动清除浏览器缓存或调用API删除)[^3] | | **作用域** | 只限于当前标签页内(不同标签页即使同源也无法共享)[^3] | 同源(相同域名、协议、端口)的所有标签页共享数据[^3] | | **存储大小** | 通常约5MB(不同浏览器可能略有差异)[^2] | 通常约5MB(比Cookie的4KB更大,支持更复杂数据)[^2] | | **典型应用场景** | 临时数据(如未提交表单内容、单页应用会话状态)[^3] | 持久数据(如用户主题设置、登录token缓存)[^2] | **关键解释:** - **生命周期区别**:SessionStorage的数据在页面会话结束时销毁。例如,用户刷新页面或导航到同源其他页面时数据保留,但关闭标签页后即消失;而LocalStorage数据会永久保存,除非用户主动清除(通过浏览器设置或API调用)[^3]。 - **作用域区别**:SessionStorage是“标签页隔离”的,即使打开多个相同URL的标签页,每个标签页的SessionStorage独立;LocalStorage则在同源下全局共享,这意味着一个标签页的数据变化会被另一个标签页检测到[^3]。 - **存储限制**:两者均提供约5MB空间,远超Cookie的4KB限制,适合存储结构化数据(如JSON对象),而无需随HTTP请求发送,减少了带宽消耗[^2][^4]。 ### 二、如何在本地存储中添加移除数据 SessionStorageLocalStorage使用相同的API进行操作(包括添加、读取移除数据),所有方法均为同步执行。以下基于JavaScript示例逐步说明。核心API包括: - `setItem(key, value)`: 添加或修改数据。 - `getItem(key)`: 读取数据。 - `removeItem(key)`: 移除单个数据项。 - `clear()`: 移除所有数据(仅针对当前存储对象)。 #### 1. 添加数据(存储数据项) 使用`setItem(key, value)`方法添加数据。键(key)必须是字符串,值(value)也必须是字符串。如果存储对象(如JSON),需先序列化。 ```javascript // 添加数据到LocalStorage(永久存储localStorage.setItem('userTheme', 'dark'); // 存储字符串 localStorage.setItem('userData', JSON.stringify({ name: 'Alice', age: 30 })); // 存储对象:先用JSON.stringify转换 // 添加数据到SessionStorage(临时会话存储sessionStorage.setItem('formDraft', '未提交内容'); // 当前标签页临时存储 ``` - **注意**:如果key已存在,`setItem`会覆盖旧值。值只能是字符串,非字符串数据(如数组或对象)需通过`JSON.stringify`转换[^4][^5]。 #### 2. 读取数据(获取存储值) 使用`getItem(key)`读取数据。返回值为字符串,如果数据是对象,需用`JSON.parse`解析。 ```javascript // 从LocalStorage读取数据 const theme = localStorage.getItem('userTheme'); // 返回字符串 'dark' const userData = JSON.parse(localStorage.getItem('userData')); // 解析为对象:{name: 'Alice', age: 30} // 从SessionStorage读取数据 const draft = sessionStorage.getItem('formDraft'); // 返回字符串 '未提交内容' ``` - **注意**:如果key不存在,`getItem`返回`null`。在读取时,建议检查返回值以避免错误[^4]。 #### 3. 移除数据 分为移除单个项清除所有数据: - **移除单个数据项**:使用`removeItem(key)`。 - **清除所有数据**:使用`clear()`,这会删除当前存储对象(LocalStorageSessionStorage中的所有数据。 ```javascript // 移除LocalStorage中的单个项 localStorage.removeItem('userTheme'); // 移除key为'userTheme'的数据 // 移除SessionStorage中的单个项 sessionStorage.removeItem('formDraft'); // 清除所有LocalStorage数据(只影响当前域) localStorage.clear(); // 清除所有SessionStorage数据(只影响当前标签页) sessionStorage.clear(); ``` - **注意事项**: - `removeItem``clear`不会引发错误,即使key不存在也不会报错[^4]。 - 当移除数据后,相关存储空间立即释放。建议在用户登出或完成操作时调用移除API,以避免数据泄露[^5]。 #### 完整示例:添加、读取移除数据 以下是一个完整的JavaScript示例,演示在LocalStorage中添加、读取移除用户配置: ```javascript // 添加数据 localStorage.setItem('config', JSON.stringify({ theme: 'light', fontSize: 16 })); // 读取数据 const config = JSON.parse(localStorage.getItem('config')); console.log(config.theme); // 输出: 'light' // 移除单个项 localStorage.removeItem('config'); // 清除所有(可选) // localStorage.clear(); ``` SessionStorage操作方式完全相同,只需将`localStorage`替换为`sessionStorage`。 ### 关键注意事项 - **数据安全**:避免存储敏感信息(如密码),因为Web Storage易受XSS攻击。推荐使用HttpOnly Cookie或后端会话管理[^1][^4]。 - **数据类型**:值必须是字符串。处理对象时,务必使用`JSON.stringify()`存储`JSON.parse()`读取[^4]。 - **存储上限**:超过5MB会抛出`QuotaExceededError`错误。添加前可检查长度:`localStorage.getItem(key)?.length`[^2]。 - **事件监听**:当LocalStorage在同源页面间变化时,可通过`storage`事件监听(SessionStorage变化不触发此事件)[^3]: ```javascript window.addEventListener('storage', (e) => { console.log(`键 ${e.key} 已更新: 旧值 ${e.oldValue}, 新值 ${e.newValue}`); }); ``` ###
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值