Laravel传输GZ压缩数据至前端JS的自动/手动解压方案
解决方案
一、浏览器自动解压(最优方案)
浏览器原生支持gzip内容自动解压,但需要后端正确设置响应头,明确告知浏览器内容的压缩格式。
修改Laravel路由代码
原路由未配置关键响应头,需补充Content-Encoding和正确的Content-Type:
Route::get('/chunks/{index}', function ($index) { $path = 'public/chunks_'.$index.'.json.gz'; if (!Storage::exists($path)) { abort(404); } $content = Storage::get($path); return response($content) ->header('Content-Type', 'application/json') ->header('Content-Encoding', 'gzip') ->header('Cache-Control', 'public, max-age=31536000'); // 可选,添加长期缓存优化加载速度 });
配置后浏览器会自动完成解压,前端无需额外处理压缩逻辑。
调整前端Fetch代码
移除错误的Content-Type: application/zip配置,直接解析JSON即可:
public static async getZipFile(url: string, params: any = {}, method = "GET", headers: any = {}){ headers['X-Requested-With'] = 'XMLHttpRequest'; const options: any = { 'method': method, 'headers': headers }; url += "?" + new URLSearchParams(params).toString(); const response = await fetch(url, options); return response.json(); // 浏览器已自动解压,直接解析JSON }; // 调用示例 let chunks = await getZipFile("/chunks/0");
二、前端手动解压(备用场景)
若无法修改后端配置,可使用浏览器原生DecompressionStreamAPI手动解压,无需第三方库:
public static async getZipFile(url: string, params: any = {}, method = "GET", headers: any = {}){ headers['X-Requested-With'] = 'XMLHttpRequest'; const options: any = { 'method': method, 'headers': headers }; url += "?" + new URLSearchParams(params).toString(); const response = await fetch(url, options); const blob = await response.blob(); // 通过gzip解压流处理二进制数据 const stream = blob.stream().pipeThrough(new DecompressionStream('gzip')); const reader = stream.getReader(); const decoder = new TextDecoder(); let result = ''; while (true) { const { done, value } = await reader.read(); if (done) break; result += decoder.decode(value, { stream: true }); } result += decoder.decode(); // 处理剩余字节 return JSON.parse(result); };
该API支持Chrome 80+、Firefox 113+、Edge 80+,覆盖绝大多数现代浏览器。
三、Zlib报错原因及替代方案
你遇到的Can't resolve './zlib_bindings'错误,是因为Node.js的zlib模块依赖底层系统绑定,无法在浏览器环境运行。若偏好第三方库,可使用前端专用的pako:
// 先安装依赖:npm install pako import pako from 'pako'; public static async getZipFile(url: string, params: any = {}, method = "GET", headers: any = {}){ headers['X-Requested-With'] = 'XMLHttpRequest'; const options: any = { 'method': method, 'headers': headers }; url += "?" + new URLSearchParams(params).toString(); const response = await fetch(url, options); const arrayBuffer = await response.arrayBuffer(); const decompressedStr = pako.inflate(new Uint8Array(arrayBuffer), { to: 'string' }); return JSON.parse(decompressedStr); };
内容的提问来源于stack exchange,提问作者NotDavid
相关产品推荐
相关产品推荐

