javascript 如何修改service worker中的当前响应?
javascript how to modify the current response in service worker?
我使用 service worker 修改获取响应,代码如下,
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();
})
);
});
这将导致此警告和错误,
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
如果我像下面这样把 clone()
放在 arrayBuffer()
之前,
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;
})
);
});
会导致以下警告和错误,
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
如果我没记错的话,您首先要复制该响应。
当您对其调用 arrayBuffer()
时,您将无法再克隆它。
尝试用解密的字节实例化并返回一个新的Response()
:
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
}
)
}
我使用 service worker 修改获取响应,代码如下,
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();
})
);
});
这将导致此警告和错误,
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
如果我像下面这样把 clone()
放在 arrayBuffer()
之前,
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;
})
);
});
会导致以下警告和错误,
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
如果我没记错的话,您首先要复制该响应。
当您对其调用 arrayBuffer()
时,您将无法再克隆它。
尝试用解密的字节实例化并返回一个新的Response()
:
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
}
)
}