2016-01-15 81 views
1

我正在使用angularjs,nodejs和socketio進行通信。文件沒有通過socket.io發送

客戶端HTML:

<div style='height: 0px;width: 0px; overflow:hidden;'> 
    <input id="avatarInput" type="file" value="upload" onchange="angular.element(this).scope().upload(this)" /> 
</div> 
<button data-ng-click="avatarButton()">Upload image</button> 

客戶端JS:

$scope.avatarButton = function() { 
    document.getElementById('avatarInput').click(); 
} 
$scope.upload = function (file) { 
    console.log('client: ' + file.type); 
    socket.emit('image', { 
     file: file 
    }); 
} 

上述結果輸出:client: file當我選擇一個.png要打開的文件。

服務器的NodeJS:

.on('image', function (data) { 
    console.log('server: ' + data.file.type); 
}) 

上述結果在輸出:server: undefined

我猜這個文件沒有通過socket.io發送到服務器。我在這裏看不到錯誤。更多的文檔在這裏:http://socket.io/blog/introducing-socket-io-1-0/#binary

從文檔報價:

Socket.IO現在支持發射緩衝器(來自Node.js的),斑點, ArrayBuffer甚至文件,因爲任何數據結構的一部分:

工作代碼:

客戶端HTML:

<div style='height: 0px;width: 0px; overflow:hidden;'> 
    <input id="avatarInput" type="file" value="upload" onchange="angular.element(this).scope().upload(this.files)" /> 
</div> 
<button data-ng-click="avatarButton()">Upload image</button> 

客戶端JS:

$scope.avatarButton = function() { 
     document.getElementById('avatarInput').click(); 
    } 
    $scope.upload = function (files) { 
     if (window.File && window.FileReader && window.FileList && window.Blob) { 
      socket.emit('uploadAvatar', { 
       file: files[0] 
      }); 
     } else { 
      alert('The File APIs are not fully supported in this browser.'); 
     } 
    } 

服務器的NodeJS:

.on('uploadAvatar', co.wrap(function* (data) { 
     console.log(data.file); // spits out buffer 
     var fs = require('fs'); 
     fs.writeFile(__dirname + '/public/avatar/myFile.png', data.file, { 
      flag: "w" 
     }, function (err) { 
      if (err) 
       return console.log(err); 
      console.log("The file was saved!"); 
     }); 
    })) 
+0

'angular.element(本).scope( ).upload(this)'你爲什麼這樣做? –

+0

@MartijnWelker這是一種巧妙的方式,可以設置「按鈕」的樣式,並使其像表單/文件輸入一樣。純粹爲了演出。例如,爲IE設計樣式文件輸入是一件痛苦的事情。 –

+0

不應該使用'FileReader'的實例來發送blob嗎? – maurycy

回答

0

它應該是這樣的(見註釋)

$scope.upload = function (element) { //element is an input[file] 
    console.log('client: ' + element.files); //a FileList object that can be send 
    socket.emit('image', { 
     file: element.files //or element.files[0] depending of what you want to achieve 
    }); 
} 
+0

確實你是對的。我不知道爲什麼我認爲單個表單文件輸入沒有被封裝在一個數組中。 TA! –

+0

我認爲你仍然必須創建緩衝區/ blob或fileReader來發送文件的內容到socket.io – maurycy

+0

它現在實際上完美地工作(通過發送文件,而不是blob):)我做了一個console.log文件發送並且足夠真實,這是一個緩衝區出來。用工作代碼更新了問題! –