2016-08-05 86 views
0

我正在为下载功能编写处理程序。当用户点击他\她的浏览器中的下载按钮时,会调用下载处理程序,然后开始下载(仅限mp3文件)。我有这个工作在PHP,但我已经改变了我的项目上的所有节点,我似乎无法得到最后一部分在Node上工作。如何从节点服务器下载文件(仅使用节点模块,无需明文等)

这是PHP代码我以前的工作:

<?php 
    header("Content-Type: application/octet-stream"); 
    header("Content-Disposition: attachment; filename=".($_GET['title'])); 
    readfile($_GET['path']); 
?> 

这是为节点的新代码:

function download(response, request){ 

var body = []; 
    request.on('data', function(chunk) { 
    body.push(chunk); 
}); 

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

    body = Buffer.concat(body).toString(); 
    var data = qs.parse(body); 
    var title = data.songTitle; 
    var filePath = __dirname + "/../myproject/songs/"+title+".mp3"; 

    fs.open(filePath,'r',function(err, fd){ 

     if(!err){ 

      fs.readFile(fd, function(err, data){ 

      if(!err){ 

       var rs = fs.createReadStream(filePath); 
       response.writeHead(200, {"Content-Type": "application/octet-stream", 
             "Content-Disposition": "attachment; filename="+title+".mp3", 
             "Content-Length" : data.length}); 
       rs.pipe(response); 
       response.on("end",function(){ 
        fs.close(fd); 
       }); 

      }else{ 

       console.log("Error while trying to read: ", err); 

      } 

      }); 

     }else{ 
      console.log("Error could not open: ", err); 
     } 

    }); 


}); 

当试图下载,我没有得到任何错误,但没有发生。我也尝试过用于内容类型的“audio/mpeg3”,没有任何内容。关于发生什么事的任何想法?请记住,我正在尝试在不使用第三方模块的情况下执行此操作。 请注意,函数download不作为http.createServer()的回调函数传递。所以响应和请求的顺序是不是问题:)

+0

我不是100%,但它看起来像将文件传递给响应变量,而不是response.write()方法。你可以尝试,response.write(rs);而不是行rs.pipe(response); – Cruiser

+0

管道应该工作。 – robertklep

回答

1

它看起来像你切换requestresponse。此外,而不是使用fs.open()/fs.readFile()来确定文件的大小,你可以使用fs.stat(),这应该是更加资源友好的(因为它不需要将整个文件加载到内存中第一):

function download(request, response) { 
    var body = []; 

    request.on('data', function(chunk) { 
    body.push(chunk); 
    }); 

    request.on('end', function() { 
    var data  = qs.parse(Buffer.concat(body).toString()); 
    var title = data.songTitle; 
    var filePath = title + '.mp3'; 

    fs.stat(filePath, function(err, stats) { 
     if (err) { 
     response.statusCode = 500; 
     return response.end(); 
     } 
     response.writeHead(200, { 
     "Content-Type"  : "application/octet-stream", 
     "Content-Disposition" : "attachment; filename="+title+".mp3", 
     "Content-Length"  : stats.size, 
     }); 
     fs.createReadStream(filePath).pipe(response); 
    }); 
    }); 
} 
+0

hmmm ... res和req按顺序传递,因为如何设置处理程序的路由器。像这样的东西... function onRequest(request,response){ \t \t var pathname = url.parse(request.url).pathname; \t \t route(handle,pathname,response,request,extensions); \t}我试过使用fs.stat。但仍然没有... –

+0

@OsaguiAghedo如果调用者按照该顺序传递参数,再次切换它们:)但是我会建议使用'request,response'作为参数顺序,因为这是Node中的常见约定。 – robertklep

相关问题