"fetch" 事件侦听器未在服务工作者中触发,无法通过 Safari 中的多部分/表单数据发布上传文件



我正在运行一个多页应用程序,该应用程序使用服务工作者通过向所有相同的原始获取添加身份验证标头来维护跨页面加载的身份验证状态。设置非常简单(非常类似于在保留主体的同时向请求添加新的头(,总体上似乎运行良好。

我的服务人员包含以下内容:

self.addEventListener("fetch", (event) => {
console.log("FETCH CALLED");
// Check and compare origin, add Authentication header, etc...
// I'm leaving the details out because in the problem case, it never gets here.
});

在网站上,我有一个简单的表单,它从按钮触发器上传文件,如下所示:

<form action="update_logo" method="POST" enctype="multipart/form-data">
<input type="file" accept="image/*" name="upload_data" id="logo-upload-chooser" 
onchange="this.form.submit();" hidden="true">
<input type="hidden" name="brand_key" value="12345">
<input type="hidden" name="upload_file_type" value="image/*">
</form>
<script>
$("#file-upload-button").click(function() {
$("#logo-upload-chooser").trigger("click");
});
</script>

在Chrome和Firefox上,一切都很正常。选择文件后,提交表单,触发服务工作者中的fetch侦听器,在服务器上添加并验证auth头,上传文件,一切正常。但是在Safari上,获取侦听器从未被触发

有趣的是,如果我在不添加文件的情况下提交表单,这是有效的(尽管没有上传,所以没有用处(。或者,如果更改enctype,这似乎也有效,但文件不可读。似乎任何时候我都有一个格式良好的文件上传帖子;获取";事件永远不会被触发,因此永远不会调用服务工作者。再说一遍,这一切在Chrome和Firefox上都很有效,只是在Safari上不行。

这是Safari漏洞吗?有变通办法吗?提前谢谢你的建议。

我在Safari上报告了这个问题:https://bugs.webkit.org/show_bug.cgi?id=187461
不要犹豫,回复并告诉你对此感到恼火。

有一个解决方法:
将文件输入转换为data/uri并删除常规输入文件。这样做将使POST请求通过Service Worker。

formData.delete('file');
// get it as blob adn readd it as regular post field
// NB: File has to be recreated on server side using _files[file][name] and _files[file][data] to work as it was a regular file upload
var file = form.querySelector('input[type="file"]').files[0];
formData.append('_files[file][name]', file.name);
var reader = new FileReader();
reader.onload = function (e) {
formData.append('_files[file][data]', e.target.result);
doFetch(id, form, formData);
};
reader.readAsDataURL(file);

在服务器端,您将不得不做一些额外的工作来将数据/uri转换为常规文件。

最新更新