2013-12-15 1 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 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

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

소켓을 사용하는 이유는 클라이언트 쪽에서 양식을 새로 고치고 싶지 않기 때문입니다. 노드 server.on 요청 유형 모델이 새로운 html 페이지 요청에서만 작동합니까? – Pirijan

+0

내가 게시 한 예제는 서버 측용입니다. 연결성을 위해 Socket 또는 http를 사용하더라도 서버에 파일을 제출하려면 클라이언트 측에서 여전히 페이지 (또는 기본 응용 프로그램)가 필요합니다. 클라이언트에게 알림을 보내려면 서버에서 정보를 수신하고 처리하기 위해 이벤트 (예 : "sendSuccessful"이벤트)를 구현해야합니다. – bxpcsure

+0

클라이언트 측에서는 입력 onchange 이벤트 또는 이와 비슷한 이벤트가있는 경우 클라이언트에서 페이지 새로 고침을 수행하지 않고도 서버로 이벤트를 전달하는 방법은 무엇입니까 (http 서버가 '요청'을 등록하기 위해)? 어쩌면 이것의 클라이언트 측의 예가 나에게 더 명확해질 것입니다. 다시 한번 감사드립니다. – Pirijan