如何将文件(exe或rar)提供给客户端以便从node.js服务器下载?

时间:2013-05-11 18:54:01

标签: javascript node.js

我有一个node.js服务器,它为index.html提供密码的文本输入。 在服务器端密码检查之后,应该为客户端启动下载。 客户端应该无法查看文件位于服务器上的位置路径。

这是我的server.js:

var
    http = require('http'),
    qs = require('querystring'),
        fs = require('fs') ;
console.log('server started');

var host = process.env.VCAP_APP_HOST || "127.0.0.1";
var port = process.env.VCAP_APP_PORT || 1337;

http.createServer(function (req, res) {

    if(req.method=='GET') {

        console.log ( ' login request from    ' + req.connection.remoteAddress );



            fs.readFile(__dirname +'/index.html', function(error, content) {
                if (error) {
                    res.writeHead(500);
                    res.end();
                }
                else {
                    res.writeHead(200, { 'Content-Type': 'text/html' });
                    res.end(content, 'utf-8');
                }
            });


    }  // method GET  end

    else{ // method POST start


        console.log('POST request from   ' + req.connection.remoteAddress);
        var body = '';
        req.on('data', function (data) {
            body += data;

            if (body.length > 500) {
                // FLOOD ATTACK OR FAULTY CLIENT, NUKE REQUEST
                req.connection.destroy(); console.log('too much data')}
        });

        req.on('end', function () {

            var postdata = qs.parse(body);
            var password = postdata.passwordpost  ;


      if (password == '7777777') {
               console.log('the password is right, download starting');

             // ???????????????????????????????????                         here I need help from stackoverflow



      }


          else{
          console.log ('password wrong');
          fs.readFile(__dirname +'/wrongpassword.html', function(error, content) {
              if (error) {
                  res.writeHead(500);
                  res.end();
              }
              else {
                  res.writeHead(200, { 'Content-Type': 'text/html' });
                  res.end(content, 'utf-8');
              }
          });
      }
        });       // req on end function end

    }
}).listen(port, host);

我需要帮助的部分标有????????

这是我的index.html:

<html>
<body>
<br>  <br>
&nbsp;&nbsp;&nbsp; please enter your password to start your download
<br>  <br>

<form method="post" action="http://localhost:1337">
    &nbsp;&nbsp;&nbsp;
    <input type="text" name="passwordpost" size="50"><br><br>
    &nbsp;&nbsp;&nbsp;   &nbsp;&nbsp;&nbsp; &nbsp;
    <input type="submit" value="download" />
</form>

</body>
</html>

你知道怎么做吗?

4 个答案:

答案 0 :(得分:5)

当然,您可以在代码中使用它:

res.setHeader('Content-disposition', 'attachment; filename='+filename);
//filename is the name which client will see. Don't put full path here.

res.setHeader('Content-type', 'application/x-msdownload');      //for exe file
res.setHeader('Content-type', 'application/x-rar-compressed');  //for rar file

var file = fs.createReadStream(filepath);
//replace filepath with path of file to send
file.pipe(res);
//send file

答案 1 :(得分:4)

您需要声明并要求pathpath = require("path")

然后可以做到:

var uri = url.parse(request.url).pathname
    , filename = path.join(process.cwd(), uri);

path.exists(filename, function(exists) {
    if(!exists) {
        response.writeHead(404, {"Content-Type": "text/plain"});
        response.write("404 Not Found\n");
        response.end();
        return;
    }
response.writeHead(200);
response.write(file, "binary");
response.end();
}

检查这些完整的example

答案 2 :(得分:2)

如果您愿意使用快速Web框架,那么可以通过更简单的方式完成。

app.get('/download', function(req, res){
  var file = __dirname + 'learn_express.mp4';
  res.download(file); // Sets disposition, content-type etc. and sends it
});

Express download API

答案 3 :(得分:0)

我找到了一些关于fs.createReadStream()(尤其是错误处理)here的其他信息,并将其与user568109的答案相结合。这是我的工作下载服务器:

var
    http = require('http'),
    qs = require('querystring'),
        fs = require('fs') ;
console.log('server started');

var host = process.env.VCAP_APP_HOST || "127.0.0.1";
var port = process.env.VCAP_APP_PORT || 1337;

http.createServer(function (req, res) {

    if(req.method=='GET') {

        console.log ( ' login request from    ' + req.connection.remoteAddress );



            fs.readFile(__dirname +'/index.html', function(error, content) {
                if (error) {
                    res.writeHead(500);
                    res.end();
                }
                else {
                    res.writeHead(200, { 'Content-Type': 'text/html' });
                    res.end(content, 'utf-8');
                }
            });


    }  // method GET  end

    else{ // method POST start


        console.log('POST request from   ' + req.connection.remoteAddress);
        var body = '';
        req.on('data', function (data) {
            body += data;

            if (body.length > 500) {
                // FLOOD ATTACK OR FAULTY CLIENT, NUKE REQUEST
                req.connection.destroy(); console.log('too much data')}
        });

        req.on('end', function () {

            var postdata = qs.parse(body);
            var password = postdata.passwordpost  ;


      if (password == '7777777') {
               console.log('the password is right, download starting');


          res.setHeader('Content-disposition', 'attachment; filename='+'test1.exe');
//filename is the name which client will see. Don't put full path here.

          res.setHeader('Content-type', 'application/x-msdownload');      //for exe file
          res.setHeader('Content-type', 'application/x-rar-compressed');  //for rar file

          var readStream = fs.createReadStream('/test1.exe');
//replace filepath with path of file to send
          readStream.on('open', function () {
              // This just pipes the read stream to the response object (which goes to the client)
              readStream.pipe(res);
          });

          // This catches any errors that happen while creating the readable stream (usually invalid names)
          readStream.on('error', function(err) {
              console.log (err)  ;
              res.writeHead(200, { 'Content-Type': 'text/html' });
              res.end('an error occured', 'utf-8');

          });
//send file



      }


          else{
          console.log ('password wrong');
          fs.readFile(__dirname +'/wrongpassword.html', function(error, content) {
              if (error) {
                  res.writeHead(500);
                  res.end();
              }
              else {
                  res.writeHead(200, { 'Content-Type': 'text/html' });
                  res.end(content, 'utf-8');
              }
          });
      }
        });       // req on end function end

    }
}).listen(port, host);