javascript如何修改服务工作者中的当前响应?
我使用 service worker 用下面的代码修改 fetch 响应,
self.addEventListener('install', function(event) {console.log('安装');});self.addEventListener('activate', function(event) {console.log('声明控制');返回 self.clients.claim();});self.addEventListener('fetch', function(event) {console.log(获取事件")event.respondWith(fetch(event.request).then(function (response) {if(response.url.match('.mp4')){控制台日志(事件);response.arrayBuffer().then(缓冲区=>{让长度 = 100view = new Uint8Array(buffer,0,length)for(i=0,j=length - 1; i
这会导致这个警告和错误,
<块引用>"的 FetchEvent导致网络错误响应:承诺被拒绝.
<块引用>
sw.js:60 Uncaught (in promise) TypeError: Failed to execute 'clone' on'Response':响应正文已被使用在 sw.js:60
如果我将 clone()
放在 arrayBuffer()
之前,如下所示,
self.addEventListener('install', function(event) {console.log('安装');});self.addEventListener('activate', function(event) {console.log('声明控制');返回 self.clients.claim();});self.addEventListener('fetch', function(event) {console.log(获取事件")event.respondWith(fetch(event.request).then(function (response) {if(response.url.match('.mp4')){控制台日志(事件);responseCloned = response.clone();responseCloned.arrayBuffer().then(缓冲区=>{让长度 = 100view = new Uint8Array(buffer,0,length)for(i=0,j=length - 1; i
这会导致以下警告和错误,
<块引用>"的 FetchEvent导致网络错误响应:a其正文"的响应被锁定不能用于响应请求.
<块引用>
GET http://localhost/web/357765_decrypted.mp4 net::ERR_FAILED
解决方案尝试实例化并返回一个新的 Response()
与解密的字节:
self.addEventListener('fetch', event => {if (event.request.url.endsWith('.mp4') {event.respondWith(getDecryptedResponse(event.request))}})异步函数 getDecryptedResponse(request) {常量响应 = 等待获取(请求)const bytes = new Uint8Array(await response.arrayBuffer())返回新的响应(新 Blob([decryptMp4Bytes(字节)],{类型:'application/mp4'}),{headers: response.headers,//这种情况下可能需要})}
I use service worker to modify the fetch response with below code,
self.addEventListener('install', function(event) {
console.log('install');
});
self.addEventListener('activate', function(event) {
console.log('Claiming control');
return self.clients.claim();
});
self.addEventListener('fetch', function(event) {
console.log("fetch event")
event.respondWith(
fetch(event.request).then(function (response) {
if(response.url.match('.mp4')){
console.log(event);
response.arrayBuffer().then(
buffer =>{
let length = 100
view = new Uint8Array(buffer,0,length)
for(i=0,j=length - 1; i<j; i++,j--){
view[i] = view[i] ^ view[j]
view[j] = view[j] ^ view[i]
view[i] = view[i] ^ view[j]
}
}
)
}
return response.clone();
})
);
});
Whichi will lead to this warning and error,
The FetchEvent for "" resulted in a network error response: the promise was rejected.
sw.js:60 Uncaught (in promise) TypeError: Failed to execute 'clone' on 'Response': Response body is already used at sw.js:60
If I put the clone()
before arrayBuffer()
like below,
self.addEventListener('install', function(event) {
console.log('install');
});
self.addEventListener('activate', function(event) {
console.log('Claiming control');
return self.clients.claim();
});
self.addEventListener('fetch', function(event) {
console.log("fetch event")
event.respondWith(
fetch(event.request).then(function (response) {
if(response.url.match('.mp4')){
console.log(event);
responseCloned = response.clone();
responseCloned.arrayBuffer().then(
buffer =>{
let length = 100
view = new Uint8Array(buffer,0,length)
for(i=0,j=length - 1; i<j; i++,j--){
view[i] = view[i] ^ view[j]
view[j] = view[j] ^ view[i]
view[i] = view[i] ^ view[j]
}
}
)
}
return responseCloned;
})
);
});
It will lead to below warning and error,
The FetchEvent for "" resulted in a network error response: a Response whose "body" is locked cannot be used to respond to a request.
GET http://localhost/web/357765_decrypted.mp4 net::ERR_FAILED
解决方案
Try instantiating and returning a new Response()
with the decrypted bytes:
self.addEventListener('fetch', event => {
if (event.request.url.endsWith('.mp4') {
event.respondWith(getDecryptedResponse(event.request))
}
})
async function getDecryptedResponse(request) {
const response = await fetch(request)
const bytes = new Uint8Array(await response.arrayBuffer())
return new Response(
new Blob([ decryptMp4Bytes(bytes) ], { type: 'application/mp4' }),
{
headers: response.headers, // possibly required for this case
}
)
}
相关文章