【问题标题】:Is it possible to detect an immediate when sending a chunky POST request with AXIOS使用 AXIOS 发送大块 POST 请求时是否可以检测到立即数
【发布时间】:2020-11-27 00:57:09
【问题描述】:

我在 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 秒:

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

提前致谢!

【问题讨论】:

    标签: node.js express axios xmlhttprequest multipartform-data


    【解决方案1】:

    我相信你可以只使用 res.status(403) 而不是 res.status(403).send() 。

    您也可以尝试使用 res.status(403).end(),但我不确定您为什么应该在路由器部分使用 return 语句。

    【讨论】:

    【解决方案2】:

    似乎首先发送响应标头并然后手动销毁请求可以解决问题:

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

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

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

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

    【讨论】:

      猜你喜欢
      • 2019-11-18
      • 1970-01-01
      • 1970-01-01
      • 2022-01-15
      • 1970-01-01
      • 2020-06-05
      • 1970-01-01
      • 2020-02-29
      相关资源
      最近更新 更多