实习遇到的一个问题:
Cookie存储了用户鉴权的各种url信息,导致单个Cookie的大小大于浏览器的Cookie最大值4KB而存储失败
CSDN大佬分享了非常多的解压办法,比如我看到的有:
1.减小Cookie大小,Cookie的domain细化等等
2.把较大值存入到LocalStorage中
3.压缩Cookie
...............
结合项目的实际情况我使用了压缩Cookie的方法
压缩Cookie的好处和坏处:
好处:
- 减少带宽使用: 压缩Cookie可以减少数据传输的大小,从而节省带宽。
- 提高加载速度: 减小的Cookie可以加快页面加载速度,尤其是在移动网络或慢速网络上。
- 改善用户体验: 较小的请求头可以减少延迟,提供更好的用户体验。
坏处:
- 处理开销: 压缩和解压缩Cookie需要额外的CPU资源,可能会增加服务器的负担。
- 兼容性问题: 不是所有客户端都支持压缩或解压缩,尤其是老旧的浏览器或设备。
- 安全性问题: 如果压缩算法在客户端是透明的,那么可能存在被篡改的风险。
- 复杂性增加: 实现Cookie压缩和解压缩的代码可能会增加系统的复杂性。
JAVA后端代码实现:具体使用工具类 :
java.util.zip.Deflater; java.util.Base64;
压缩代码:
private static String compressAndEncode(String data) {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
Deflater deflater = new Deflater(Deflater.DEFAULT_COMPRESSION, true);
try (DeflaterOutputStream deflaterOutputStream = new DeflaterOutputStream(byteArrayOutputStream, deflater)) {
deflaterOutputStream.write(data.getBytes());
deflaterOutputStream.finish(); // 确保所有数据都被写入
} catch (IOException e) {
e.printStackTrace();
return null; // 处理异常
}
// 将压缩后的字节数据转换为Base64编码的字符串
return Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray());
}
然后将方法的返回值存入cookie中返回
扩展:Deflater:
构造函数Deflater(int level, boolean nowrap)
有两个参数:
-
level
:压缩级别,取值范围通常是从Deflater.NO_COMPRESSION
(不压缩)到Deflater.BEST_COMPRESSION
(最大压缩)。Deflater.DEFAULT_COMPRESSION
代表默认压缩级别,这是一个平衡了压缩率和压缩速度的级别。 -
nowrap
:如果设置为true
,表示压缩时不包含 zlib 头和校验和。false
则表示包含这些额外的信息,使得压缩数据可以被zlib兼容的解压器解压。
扩展 :对应的解压代码:
public static String compressAndDecode(String data) {
Base64.Decoder decoder = Base64.getDecoder();
byte[] decode = decoder.decode(data);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
Inflater decompressor = new Inflater(true);
try {
decompressor.setInput(decode);
final byte[] buf = new byte[2048];
while (!decompressor.finished()) {
int count = decompressor.inflate(buf);
bos.write(buf, 0, count);
}
System.out.println(bos.toString());
} catch (DataFormatException e) {
throw new RuntimeException(e);
} finally {
decompressor.end();
}
}
vue pako前端处理:
前端是使用了pako来解压Cookie,我用的版本是pako版本是2.1.0
import pako from 'pako';
const userInfoKey = 'user-info'
export function getCookieUserInfo() {
const str =Cookies.get(userInfoKey);
const arr = new Uint8Array([...atob(str)].map(c => c.charCodeAt(0)));
const data = pako.inflateRaw(arr, { to: "string" });
return JSON.parse(data)
}
调用的是pako.inflateRaw()
如果使用pako.inflate
而不是pako.inflateRaw
,由于压缩数据没有zlib头,可能会遇到“incorrect header check”的错误。这是因为pako.inflate
期望压缩数据包含zlib头信息。