2013-12-15 32 views
0

我想實現一個文件上傳在HTML5/js和節點上傳大塊文件的塊。它適用於單個上傳。但是,當我嘗試在同一頁面上再次上傳時,它會進入無限循環,看起來它正試圖重新上傳先前的上傳文件和新文件。Filereader和Socket.io上傳:後續上傳包括以前上傳

Client.js

$('input').change(function() { 
    var file = this.files[0] 
    var fileSize = file.size 
    var fileName = file.name 
    // file size gate: 
    var fileSizeLimit = 15000000 // ~15mb 
    if (fileSize <= fileSizeLimit) { 
    // get preview blob 
    var windowURL = window.URL || window.webkitURL 
    var blobURL = windowURL.createObjectURL(this.files[0]) 
    // render preview image 
    // render status progress 
    // set progress to 0 

    // read the file to server: 
    var reader = new FileReader() 
    console.log('new filereader init') 
    socket.emit('startSend', fileName, fileSize, entryID) 
    console.log('startSend emitted now for ' + fileName) 

    reader.onload = function(event) { 
     var data = event.target.result 
     console.log('reader onload for ' + fileName) 
     socket.emit('sendPiece', data, fileName, fileSize, entryID) 
    } 

    socket.on('morePlease', function (place, entryID, percent){ 
     progressUpdate(percent) 
     var chunkSize = 262144 
     var startPlace = place * chunkSize // The newBlock's Starting Position 
     var newBlock = file.slice(startPlace, startPlace + Math.min(chunkSize, (fileSize-startPlace))) 
     reader.readAsBinaryString(newBlock) // triggers reader onload 
    }) 

    function progressUpdate(percent){ 
     console.log('current percent is: ' + percent + '%') 
     $('.sendfile .progress').val(percent).text(percent + '%') 
    } 

    socket.on('sendSuccessful', function(entryID){ 
     console.log('sendSuccessful triggered for ' + entryID + '. File should be in temp folder.') 
     $('.status .sendfile').addClass('hidden') 
     $('.status .savetext').removeClass('hidden') 
     $('.status .saved').removeClass('hidden') 
     $('.sendfile .progress').val(0).text('0%') 
    }) 

    } else { 
    // file size is too big 
    } 

}) // close input onchange event 

Server.js


服務器日誌:這是基於分散在整個console.logs節點日誌:

上傳第一文件很好:

startSend hit for file1.jpeg 
place: in startSend, the place for file1.jpeg is 0 
sendPiece hit for 52a530f8649b5db8b2000001 file1.jpeg 
file 52a530f8649b5db8b2000001has been written to temp folder: file1.jpeg 

,併爲後續的文件:

startSend hit for file2.JPG 
place: in startSend, the place for file2.JPG is 0 
sendPiece hit for 52a530f8649b5db8b2000001 file1.jpeg 
MorePlease: file1.jpeg pieces needed at place 1.9332275390625 and percent undefined 
sendPiece hit for 52a530f8649b5db8b2000001 file1.jpeg 
MorePlease: file1.jpeg pieces needed at place 0.96661376953125 and percent undefined 
sendPiece hit for 52a530f8649b5db8b2000001 file2.JPG 
MorePlease: file2.JPG pieces needed at place 2.6120567321777344 and percent undefined 

...無限循環。


webinspector消息:

reader onload for file1.jpeg (client.js, line 260) 
reader onload for file2.JPG (client.js, line 260) 
current percent is: 270.227552566774% (client.js, line 273, x2) 
current percent is: 242.3942545981759% (client.js, line 273) 
InvalidStateError: DOM Exception 11: An attempt was made to use an object that is not, or is no longer, usable. 

...無限循環


我已經費盡我的大腦在這幾個小時,試圖通過代碼在我自己的步驟。我不是貿易開發商,所以任何幫助都會超級讚賞!

回答

0

我從來沒有使用Socket來上傳Node.js文件。基本上,http做得很好。這是示例代碼:

var http = require('http'), 
    fs = require('fs'); 

var server = http.createServer(); 
server.listen(8080); 
console.log('Start is started on port 8080'); 

server.on('request', function(req, res) { 
    var file = fs.createWriteStream('sample.jpg'); 
    var fileSize = req.headers['content-length']; 
    var uploadedSize = 0; 

    req.on('data', function (chunk) { 
     uploadedSize += chunk.length; 
     var buffer = file.write(chunk); 
     if(buffer == false) 
      req.pause(); 
    }); 

    file.on('drain', function() { 
     req.resume(); 
    }); 

    req.on('end', function() { 
     res.write('File uploading is completed!!'); 
     res.end(); 
    }); 
}); 

如果你要通知進度上傳客戶端,您可以在data事件中添加一些邏輯。

順便說一句,我發現有人已經問過同樣的問題並得到答案。答案發布了一個教程的鏈接。我已經檢查並認爲它是您正在尋找的解決方案。檢查這個Node.js file upload capabilities: Large Video Files Uploading with support for interruption

+0

我使用socket的原因是因爲我不想在客戶端提交表單時進行頁面刷新。節點server.on請求類型模型僅適用於新的html頁面請求嗎? – Pirijan

+0

我發佈的例子是針對服務器端的。即使您使用Socket或http進行連接,您仍然需要客戶端的頁面(或本機應用程序)將文件提交到服務器。如果你希望你的客戶端得到通知,它必須實現事件(如「sendSuccessful」事件)來接收和處理來自服務器的信息。 – bxpcsure

+0

在客戶端,使用輸入onchange事件或類似的情況下,如何將事件傳遞給服務器,而不必觸發客戶端上的頁面刷新(用於註冊'請求'的http服務器)?也許這個客戶端的一個例子會讓我更清楚。再次感謝。 – Pirijan