为什么express的res.download()方法导致“请求中止”?错误? [英] Why is express' res.download() method causing a "request aborted" error?

查看:623
本文介绍了为什么express的res.download()方法导致“请求中止”?错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从使用 express 框架的 node.js 服务器获得以下代码:

  var fs = require('fs')
express = require('express')
把手= require('快速车把');

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

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

app.listen(3001);

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

  {错误:onaborted(/home/js/webdev/fs/node_modules/express/lib/response.js:1021:15)请求中止的

在Instant._onImmediate(/home/js/webdev/fs/node_modules/express/lib/response.js:1063:9)
在runCallback(timers.js:696:18)
在tryOnImmediate(timers.js:667:5)
在processImmediate(timers.js:649:5)代码:'ECONNABORTED'}

如果 res.download()更改为 res.send('Helo'),它起作用。



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



谢谢。

解决方案

您不允许使用 res。 download()完成



错误:请求中止表示快递没有



当您呼叫 res.download()时,它的 等同于执行 res.send(),只是要确保它具有足够的标头让浏览器知道它是文件下载,而不是在浏览器中显示。此函数调用为 asynchronous ,这意味着它将继续在后台运行,然后运行下一行代码,在本例中为 next()



next()被调用,然后告诉express继续寻找匹配的路线,或者,在这种情况下,不再有匹配和表达的路由终止连接。这不是您想要的,因为您仍在尝试完成文件下载。



如何解决它? / h3>

非常简单,如果路由不是,请确保快递不能继续到中间件中的下一条路由/ 。在条件中添加 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),下载.png,err => {
if(err)console.log(err);
});
});

app.listen(3001);




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.

解决方案

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 accomplish 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

这篇关于为什么express的res.download()方法导致“请求中止”?错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆