首页 > 解决方案 > 使用 AXIOS 发送大块 POST 请求时是否可以检测到立即数

问题描述

我在 Web 客户端中使用 AXIOS,以便将文件作为上传上传到 express 后端。由于文件的大小和客户端用户的带宽都是可变的,因此 POST 请求可能需要一定的时间才能完成。在后端应用了一些逻辑,请求被立即拒绝。

问题是客户端只有在请求完成后才收到响应,这可能是几秒钟。

我已经测试过这不是后端的错,因为无论技术如何,在网络中发布到任何启用后的任意 URL 时,行为都是相同的。这是该案例的(过度)简化示例。

这是发布操作。请注意对任意启用后 URL 的推荐请求。它的行为完全相同:

try{
    console.log("posting....")
    const res = await axios.post("http://localhost:4000/upload", formData)
    // const res = await axios.post("https://github.com/logout", formData)
    console.log("result:")
    console.log(res)
}catch(err){
    console.error(err)
}

以及demo express后端路由:

app.post("/upload", (req, res) => {
    console.log("Rejecting...")
    res.status(403).send()
    console.log("Rejected.")
    return
})

出于测试目的,我选择了一个 3.7Mb 的文件,并将浏览器带宽限制为 Fast 3G 预设。

后端立即输出:

拒绝……拒绝。

而请求在返回 403 错误之前等待大约 43 秒:

devtools 请求检查

我在这里遗漏了一些明显的东西吗?它是如此常见的功能,这让我怀疑这是正确的处理方式。如果确实如此,我们是否有任何关于 express 的线程在那段时间是否处于活动状态的信息,或者这只是客户的不便?

提前致谢!

标签: node.jsexpressaxiosxmlhttprequestmultipartform-data

解决方案


似乎首先发送响应标头然后手动销毁请求就可以了:

app.post("/upload", (req, res) => {
    console.log("Rejecting...")
    res.status(403).send("Some message")
    return req.destroy()
})

AXIOS 请求保持未决状态,直到仅上传当前块,然后立即产生正确的状态和消息。在节流的快速 3g 示例中,挂起时间从 43 秒降至 900 毫秒。

此外,此解决方案是通过反复试验出现的,因此它可能不是最佳实践。

如果存在面向 AXIOS 的解决方案,我仍然会感兴趣。


推荐阅读