Hapi、Joi 和 Formdata 上传出现神秘的间歇性 CORS 错误
Posted
技术标签:
【中文标题】Hapi、Joi 和 Formdata 上传出现神秘的间歇性 CORS 错误【英文标题】:Mystery intermittent CORS error with Hapi, Joi, and Formdata uploads 【发布时间】:2021-11-10 01:51:06 【问题描述】:我已经调试了几天,我希望你们中的一个优秀的人之前遇到过类似的事情,并且对我们有一些想法。
MacOS 大苏尔, 客户端和 API 都是 javascript, 反应/Node.js, 哈皮/乔伊,
问题如下:某些 PDF/图像将无法上传到我们的 REST API。从来没有在 Safari 中,有时在 Firefox 中,总是在 Chrome 和 Edge 中。
API 部署到 AWS,当运行我们的本地实例时,我们无法重现此问题(当然,上传在本地永远不会失败,没有调用 CORS。本地环境与部署的环境相同)。
上传请求在使用某些文件时会一直失败,而在使用其他文件时会一直正常工作,就好像文件本身已损坏一样。例如,PDF-A 总是会失败(除非在本地发送,否则它会工作。我们在本地的 API 代码中没有失败或错误),PDF-B 永远不会失败。
我们收到这个经典错误(在 Edge 和 Chrome 中一致,在 Firefox 中是间歇性的,在 Safari 中不存在):
CORS 策略已阻止从源“http://localhost:3000”获取“https://apiUrl/relevant-endpoint”的访问权限:没有“Access-Control-Allow-Origin”标头存在于请求的资源上。如果不透明的响应满足您的需求,请将请求的模式设置为“no-cors”以获取禁用 CORS 的资源。
我们在 API 中处理 CORS,通过动态返回预检请求信息:
if (request.method === 'options')
response.statusCode = 200;
response.headers['access-control-expose-headers'] = 'content-type, content-length, etag';
response.headers['access-control-max-age'] = 60 * 10; // 10 minutes
// dynamically set allowed headers & method
if (request.headers['access-control-request-headers'])
response.headers['access-control-allow-headers'] = request.headers['access-control-request-headers'];
if (request.headers['access-control-request-method'])
response.headers['access-control-allow-methods'] = request.headers['access-control-request-method'];
return h.continue;
它已经投入生产 2 年,已经处理了几千个成功的文件上传,成千上万的请求。
我们的客户端请求如下:
function request(req)
return new Promise((resolve, reject) =>
const endpoint = `$ apiUrl $ req.endpoint `;
const options =
method: req.method.toUpperCase()
;
fetch(endpoint, options)
.then((res) => res.json())
.then((res) =>
if (res.status === 'Fail')
reject(res);
else
resolve(res.data);
)
.catch((err) =>
reject(err);
);
);
function submit(body)
const options =
endpoint: '/relevant-endpoint',
method: 'POST',
body
;
// Body : FormData ...
return new Promise((resolve, reject) =>
request(options)
.then(resolve)
.catch(reject);
);
const form = new FormData();
form.append('string A', this.state.stringA);
form.append('string B', this.state.stringB);
form.append('string C', this.state.stringC);
form.append('int A', this.state.intA);
form.append('file A', this.state.fileA); // the culprit
form.append('date A', this.state.dateA));
submit(form);
如果导致错误的文件被优化,对于 jpeg/png,或在 PDF 的情况下被编辑(即,在 Adobe 中删除的字体),它们将成功上传。我无法确切地发现导致文件失败的特征。我们能够成功提交更大或更小的文件,并且如前所述,有些文件具有相同的内容。
如有必要,我可以添加一些额外的服务器端逻辑,但我不确定问题是否与此有关。
【问题讨论】:
【参考方案1】:对于将来阅读本文的任何人,我们今天的实施取得了一些进展,但我们还没有更深入地了解这个错误。
我们有另一个文件上传部分,可以将类似文件 (new Formdata(), form.append()
) 作为数组发送。我们发现,当我们在第二个位置发送通常会触发 CORS 错误的文件时,它不会触发错误。
所以现在我们发送[ null, file ]
。如果我们发送[ file ]
或[ file, null ]
它仍然会触发错误。我希望这对任何人都有帮助,或者如果您对我们有进一步的了解,我期待了解这里到底发生了什么。谢谢!
【讨论】:
以上是关于Hapi、Joi 和 Formdata 上传出现神秘的间歇性 CORS 错误的主要内容,如果未能解决你的问题,请参考以下文章