2013-12-15 2 views
0

Я пытаюсь реализовать загрузчик файлов в html5/js и узел, который загружает большие файлы в куски. Он отлично работает для одной загрузки. Но когда я пытаюсь загрузить и снова загружать на той же странице, он переходит в бесконечный цикл, где похоже, что он пытается повторно загрузить предыдущую загрузку и новый файл сразу.Filereader и Socket.io uploader: последующие загрузки включают предыдущие загрузки

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

Причина, по которой я пошел с сокетом, заключается в том, что я не хотел обновлять страницу в форме отправки на стороне клиента. Разве модель типа request.server.on не работает только с новыми запросами на страницу html? – Pirijan

+0

Пример, который я опубликовал для серверной части. Даже если вы используете Socket или http для подключения, вам все равно нужна страница (или собственное приложение) на стороне клиента для отправки файла на сервер. Если вы хотите, чтобы ваш клиент получил уведомление, он должен реализовать событие (например, событие sendSuccessful) для получения и обработки информации с сервера. – bxpcsure

+0

В случае клиентской стороны, с вводом события onchange или что-то в этом роде, как передать событие на сервер без необходимости запуска обновления страницы на клиенте (для того, чтобы http-сервер зарегистрировал «запрос»)? Может быть, пример этого клиента сделает его более понятным для меня. Еще раз спасибо. – Pirijan

Смежные вопросы