2016-08-05 84 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