请求表单服务工作线程中的数据 - 类型错误:无法获取



我正在使用服务工作者作为代理,它抛出类型错误:无法以奇怪的方式随机获取。

有时,const formData = await request.formData();会失败并抛出类型错误:无法提取。

我将文件存储在 FormData 中,在大多数情况下await request.formData()工作正常。但是,如果它对特定文件失败一次,则下一次将失败,仅针对此特定文件。其余文件可以工作(除了这种罕见的情况(。

我将不胜感激任何可能出错的想法,是服务工作者的错误,还是可能有一组可能导致此行为的特定条件。

async function handleUploadFileRequest(request) {
const formData = await request.formData();
const file = formData.get('file');
const response = await fetch(`${endpoint}/api/v2/uploads.json?filename=${file.name}`, {
method: 'POST',
headers: {
'Content-Type': 'application/binary'
},
body: file,
});
return response.clone();
}
self.addEventListener('fetch', (event) => {
if (!token || !endpoint) {
const params = new URL(location).searchParams;
endpoint = params.get('endpoint');
token = params.get('token');
}
const handleRequest = async () => {
try {
const { request } = event;
if (request.method === 'POST') {
const isUploadFileRequest = request.url.includes('/request_uploads');
const isSubmitFormRequest = request.url.includes('/request');
if (isUploadFileRequest) {
return handleUploadFileRequest(request);
}
if (isSubmitFormRequest) {
return handleSubmitRequest(request);
}
}
if (request.method === 'DELETE') {
const isDeleteFileRequest = request.url.includes('/requests/new');
if (isDeleteFileRequest) {
return new Response(true, { status: 200 });
}
}
if (request.method === 'GET') {
const isSuggestionsRequest = request.url.includes('/suggestions');
if (isSuggestionsRequest) {
const url = request.url;
const newUrl = `${url}&jwt=${token}`;
const newRequest = new Request(newUrl, request);
const response = await fetch(newRequest);
return new Response(await response.text(), {
status: response.status,
headers: { 'content-type': 'application/json' }
});
}
const isAnswerBotRequest = request.url.includes('/answerBot.js');
if (isAnswerBotRequest) {
return new Response('var answerBot = { init: (locale) => {}};', { status: 200 });
}
}
return fetch(request);
} catch (error) {
return fetch(request);
}
};
event.respondWith(handleRequest());
});

您只能"使用"Request对象的主体一次。

handleUploadFileRequest()里面,当你打电话给request.formData()时,你最终会消耗身体。如果handleUploadFileRequest()最终出于任何原因引发异常,您的

catch (error) {
return fetch(request);
}

块被触发,此时你最终会尝试第二次消耗request的身体。这总是会失败的。

我建议进行两项更改:

  1. 在消耗request对象之前克隆其主体:
function handleUploadFileRequest(request) {
const clonedRequest = request.clone();
const formData = await clonedRequest.formData();
// ...
}

通过这样做,您将使原始Request对象的主体不受干扰。如果您希望catch()块中的fetch(request)正常工作,则需要为最终可能消耗request正文的任何代码路径调用clone()

  1. catch()处理程序添加一些日志记录,以找出引发异常的原因:
catch (error) {
console.log('Falling back to network due to: ', error);
return fetch(request);
}

我不确定当前是什么导致了您的失败,但希望一些额外的日志记录将帮助您检测出了什么问题,并且clone()应该可以让您的回退真正成功。

相关内容

最新更新