【问题标题】:Why is express' res.download() method causing a "request aborted" error?为什么 express 的 res.download() 方法会导致“请求中止”错误?
【发布时间】:2018-12-02 09:01:50
【问题描述】:

我有来自使用express 框架的node.js 服务器的以下代码:

var fs = require('fs')
    express = require('express')
    handlebars = require('express-handlebars');

var helpers = require('./lib/helpers');

var app = express();

app.use(function(req, res, next){
   var pathUrl = req.path; 
   if(pathUrl !== '/')
   res.download(__dirname + '/' + 'download.png', 'download.png', function(err){
      console.log(err);
   });
   next();
});

app.get('/', function(req, res){
   res.send('<a href=' + '/download.png' + '>' + 'download' + '</a>');
});

app.listen(3001);

运行时,此代码会产生以下错误:

{ Error: Request aborted
    at onaborted (/home/js/webdev/fs/node_modules/express/lib/response.js:1021:15)
    at Immediate._onImmediate (/home/js/webdev/fs/node_modules/express/lib/response.js:1063:9)
    at runCallback (timers.js:696:18)
    at tryOnImmediate (timers.js:667:5)
    at processImmediate (timers.js:649:5) code: 'ECONNABORTED' }

如果res.download() 更改为res.send('Helo'),它可以工作。

为什么res.download() 不起作用?

谢谢。

【问题讨论】:

    标签: javascript node.js http express download


    【解决方案1】:

    你不允许res.download() 完成

    Error: Request aborted 表示 express 还没有机会完成发送它需要发送的内容。

    当您调用res.download() 时,它相当于执行res.send(),除了确保它有足够的标题让浏览器知道这是一个文件下载,而不是在浏览器中显示的东西。这个函数调用是异步的,意味着它会在后台继续运行,然后运行下一行代码,在本例中为next()

    next() 被调用,然后告诉 express 继续寻找匹配的路由,或者,在这种情况下,没有更多匹配的路由并且 express 将终止连接。这不是您想要的,因为您仍在尝试完成文件下载。完成后不需要特意告诉你,你说什么时候完成

    如何解决?

    很简单,如果路由不是/,请确保express 不能继续到中间件中的下一个路由。在条件中添加else 子句:

    app.use(function(req, res, next){
       var pathUrl = req.path;
       if(pathUrl !== '/') {
           res.download(__dirname + '/' + 'download.png', 'download.png', function(err){
              console.log(err);
           });
       } else {
           next();
       }
    });
    

    脚注

    这不是完成您在此处尝试执行的操作的最简单方法。您可以使用通配符路由匹配 (*) 来简化此操作。我已经对您的代码进行了一些整理,其中包括其中的一些功能。

    const path = require("path");
    const express = require("express");
    const app = express();
    
    app.get("/", (req, res) => res.send(`<a href="/download.png">download</a>`));
    
    app.get("*", (req, res) => {
        res.download(path.join(__dirname, "./download.png"), "download.png", err => {
            if (err) console.log(err);
        });
    });
    
    app.listen(3001);
    
    • (req, res) =&gt; {} 是写function(req, res) {}cleaner way
    • path 模块 should be used 因为它可以处理多个操作系统
    • * 通配符路由将匹配任何内容,并且通常应该始终排在最后
    • 我们现在在console.log() 之前检查是否有err

    【讨论】:

    • 我也遇到了一个问题,在 csv 文件中计算并保存 999999 条记录后,在 res.download 时发生此错误并且路由再次启动
    猜你喜欢
    • 2019-06-30
    • 1970-01-01
    • 2021-10-16
    • 2017-12-09
    • 1970-01-01
    • 1970-01-01
    • 2022-10-05
    • 2020-07-16
    • 1970-01-01
    相关资源
    最近更新 更多