0

0

service worker如何拦截和缓存XML上传请求

幻夢星雲

幻夢星雲

发布时间:2026-03-04 09:59:03

|

487人浏览过

|

来源于php中文网

原创

service worker 能拦截 xmlhttprequest 的 post 请求但无法缓存其响应,因请求体单向消耗导致 fetch 失败;cache.put() 对上传无效因其响应无重放价值;应改用 fetch + 预读 arraybuffer 构造可复用请求,并由前端控制离线队列与 sync 重发。

service worker如何拦截和缓存xml上传请求

Service Worker 能否拦截 XMLHttpRequest 的 POST 请求?

不能直接缓存上传请求的响应体,但可以拦截并阻止默认行为——关键在于:浏览器对 XMLHttpRequest(尤其是带 send(body) 的 POST)的请求体读取是单向且不可复用的。一旦你在 fetch 事件中调用 event.request.clone().arrayBuffer() 或类似方法,原始请求体就被消耗掉了,后续 fetch(event.request) 会失败并抛出 TypeError: Failed to execute 'fetch' on 'Window': Request body is already used

为什么 cache.put() 对上传请求基本无效?

因为缓存的是响应,而 XML 上传这类请求的目标通常是服务端处理动作(如提交表单、触发任务),其响应往往无意义(200 OK 空体、204 No Content),或含动态时间戳/ID,不具备可重放性。强行缓存会导致:

  • 重复提交(用户刷新页面后 Service Worker 返回旧响应,但服务端已执行过)
  • 缓存击穿(响应体为空或极小,cache.put() 成功但无实际价值)
  • 请求体丢失导致 fetch 失败,降级为离线失败

真正可行的替代方案:用 fetch() + FormData + Request 构造可拦截的上传

必须放弃原生 XMLHttpRequest,改用 fetch() 发起上传,并确保请求体可被多次读取。核心是:不直接传原始 FormDataBlob,而是提前转为 ArrayBufferUint8Array,再构造新 Request

Logomaster.ai
Logomaster.ai

Logo在线生成工具

下载
self.addEventListener('fetch', event => {
  if (event.request.method === 'POST' && event.request.url.includes('/upload')) {
    event.respondWith((async () => {
      try {
        // 1. 提前读取 body(只做一次)
        const bodyArray = await event.request.arrayBuffer();
        
        // 2. 构造可复用的新 Request(注意:headers 需手动复制,Content-Length 会自动计算)
        const newRequest = new Request(event.request.url, {
          method: 'POST',
          headers: Object.fromEntries(event.request.headers),
          body: bodyArray
        });

        // 3. 可选:先尝试缓存匹配(对上传场景通常跳过)
        // const cached = await caches.match(newRequest);
        // if (cached) return cached;

        // 4. 转发请求到网络
        const response = await fetch(newRequest);
        
        // 5. 缓存响应?仅当响应有明确重用价值(如上传后返回资源 URL)
        // if (response.status === 200) {
        //   const cache = await caches.open('uploads');
        //   await cache.put(newRequest, response.clone());
        // }

        return response;
      } catch (err) {
        return new Response('Upload failed', { status: 503 });
      }
    })());
  }
});

注意:event.request.arrayBuffer() 是唯一安全读取方式;用 text()json() 会破坏二进制数据;FormData 实例无法被 clone() 后重复使用,必须转底层字节。

离线上传的兜底逻辑必须由前端主动控制

Service Worker 不适合自动重放上传请求。正确做法是:

  • 前端在发起 fetch('/upload', { method: 'POST', body: formData }) 前,先检查 navigator.onLine
  • 若离线,将序列化后的请求数据(URL、headers、body ArrayBuffer base64)存入 IndexedDB
  • Service Worker 中监听 sync 事件,在恢复联网后主动拉取待上传队列并重发
  • 避免在 fetch 事件里自动重试——用户可能已关闭页面,或数据已过期

真正的难点不在拦截,而在语义:上传不是 GET,它代表状态变更。缓存它的“结果”不如保证它的“送达”。fetch 事件里能做的只是可控转发,而非魔法缓存。

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

452

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

546

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

328

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

81

2025.09.10

pdf怎么转换成xml格式
pdf怎么转换成xml格式

将 pdf 转换为 xml 的方法:1. 使用在线转换器;2. 使用桌面软件(如 adobe acrobat、itext);3. 使用命令行工具(如 pdftoxml)。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

1939

2024.04.01

xml怎么变成word
xml怎么变成word

步骤:1. 导入 xml 文件;2. 选择 xml 结构;3. 映射 xml 元素到 word 元素;4. 生成 word 文档。提示:确保 xml 文件结构良好,并预览 word 文档以验证转换是否成功。想了解更多xml的相关内容,可以阅读本专题下面的文章。

2116

2024.08.01

xml是什么格式的文件
xml是什么格式的文件

xml是一种纯文本格式的文件。xml指的是可扩展标记语言,标准通用标记语言的子集,是一种用于标记电子文件使其具有结构性的标记语言。想了解更多相关的内容,可阅读本专题下面的相关文章。

1146

2024.11.28

Swift iOS架构设计与MVVM模式实战
Swift iOS架构设计与MVVM模式实战

本专题聚焦 Swift 在 iOS 应用架构设计中的实践,系统讲解 MVVM 模式的核心思想、数据绑定机制、模块拆分策略以及组件化开发方法。内容涵盖网络层封装、状态管理、依赖注入与性能优化技巧。通过完整项目案例,帮助开发者构建结构清晰、可维护性强的 iOS 应用架构体系。

2

2026.03.03

C++高性能网络编程与Reactor模型实践
C++高性能网络编程与Reactor模型实践

本专题围绕 C++ 在高性能网络服务开发中的应用展开,深入讲解 Socket 编程、多路复用机制、Reactor 模型设计原理以及线程池协作策略。内容涵盖 epoll 实现机制、内存管理优化、连接管理策略与高并发场景下的性能调优方法。通过构建高并发网络服务器实战案例,帮助开发者掌握 C++ 在底层系统与网络通信领域的核心技术。

10

2026.03.03

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号