最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Why is express' res.download() method causing a "request aborted" error? - Stack Overflow

programmeradmin5浏览0评论

I have the following code from a node.js server that uses the express framework:

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);

When run, this code creates the following error:

{ 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' }

If res.download() changes on to res.send('Helo'), it works.

Why does res.download() not work?

Thanks.

I have the following code from a node.js server that uses the express framework:

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);

When run, this code creates the following error:

{ 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' }

If res.download() changes on to res.send('Helo'), it works.

Why does res.download() not work?

Thanks.

Share Improve this question edited Jun 23, 2018 at 1:57 Brooke Holmes 1,62214 silver badges32 bronze badges asked Jun 22, 2018 at 20:55 TflagTflag 631 silver badge5 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 7

You're not allowing res.download() to finish

The Error: Request aborted means that express hasn't had a chance to finish sending what it needs to send.

When you call res.download(), it's equivalent to performing res.send() except making sure it has adequate headers for the browser to know it's a file download, instead of something to display in the browser. This function call is asynchronous, meaning that it will continue running in the background and then run the next line of code, which in this case, is next().

next() gets called, which then tells express to continue looking for routes that match, or, in this case, there are no more routes that match and express will terminate the connection. This is not what you want, as you're still trying to finish the file download. You don't need express tell you when you're done, you say when you're done.

How to fix it?

Very simply, just make sure that express cannot continue to the next route in the middleware if the route isn't /. Add an else clause to your conditional:

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();
   }
});

Footnote

This is not the easiest way to acplish what you're trying to do here. You can use wildcard route matching (*) to make this much simpler. I've given your code a little tidy up that includes some of these features.

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) => {} is a cleaner way of writing function(req, res) {}
  • the path module should be used as it can handle multiple OS's
  • the * wildcard route will match anything, and should usually always go last
  • we now check to see if there is an err before we console.log() it
发布评论

评论列表(0)

  1. 暂无评论