2013-02-09 51 views
2

我试图使用express.js和socket.io将图像保存到具有node.js的指定目录,但它不起作用。使用nodejs,expressjs和socket.io保存图像

在客户端:

var reader = new FileReader(); 
function drop(e) { 
    e.stopPropagation(); 
    e.preventDefault(); 

    var dt  = e.dataTransfer; 
    var files = dt.files; 
    jQuery.each(files, function(){ 

     reader.onload = function(e) { 
      socket.emit('sendfile', e.target.result); 
     }; 
    }); 
    return false; 
} 

图像应通过拖曳上传拖放功能。

然后在服务器端:

io.sockets.on('connection', function (socket) { 
[...] 
    socket.on('sendfile', function (data) { 
     var fs = require('fs'); 
     app.use(express.bodyParser({ keepExtensions: true, uploadDir: '/uploaded' })); 

     io.sockets.emit('updatechat', socket.username, data); //test 
    }); 

我也曾尝试

socket.on('sendfile', function (data) { 
     var fs = require('fs'); 
     fs.writeFile('/uploaded/test.png', data, "binary" , function (err) { 
      if (err) throw err; 
      console.log('It\'s saved!'); 
     }); 
     io.sockets.emit('updatechat', socket.username, data); //data test 
    }); 

但它不保存任何东西。 “数据测试”告诉我,数据已经到达服务器,所以我不认为问题来自客户端,但在服务器端,我不知道我在做什么错

回答

8

我做了一个简单的例子,通过说明文件上传的用法插座!

以下的步骤:

  1. 创建发送文件 socket.io事件收到app.js.文件收到的这个文件是一个二进制文件;
  2. 在翡翠/ HTML页面放置一个输入文件和一个按钮发送它。注意:您不必使用multipart发送包含多部分内容的帖子,我们发送套接字文件而不是TCP请求/响应;
  3. 初始化HTML5文件API支持并准备侦听器查看您的文件输入组件;
  4. 其余的例程读取文件并向前发送内容。

现在第一步(app.js):

var io = require('socket.io').listen(8000, {log: false}); 

io.sockets.on('connection', function(socket) { 
    socket.on('send-file', function(name, buffer) { 
     var fs = require('fs'); 

     //path to store uploaded files (NOTE: presumed you have created the folders) 
     var fileName = __dirname + '/tmp/uploads/' + name; 

     fs.open(fileName, 'a', 0755, function(err, fd) { 
      if (err) throw err; 

      fs.write(fd, buffer, null, 'Binary', function(err, written, buff) { 
       fs.close(fd, function() { 
        console.log('File saved successful!'); 
       }); 
      }) 
     }); 

    }); 
}); 

第二步(在我的情况下,我用玉,而HTML)

extends layout 

block content 
    h1 Tiny Uploader 
    p Save an Image to the Server 
    input#input-files(type='file', name='files[]', data-url='/upload', multiple) 
    button#send-file(onclick='javascript:sendFile();') Send 

    script(src='http://127.0.0.1:8000/socket.io/socket.io.js') 
    script(src='/javascripts/uploader.js') 

第三和第四步骤(编码上传.js发送文件到服务器)

//variable declaration 
var filesUpload = null; 
var file = null; 
var socket = io.connect('http://localhost:8000'); 
var send = false; 

if (window.File && window.FileReader && window.FileList) { 
    //HTML5 File API ready 
    init(); 
} else { 
    //browser has no support for HTML5 File API 
    //send a error message or something like that 
    //TODO 
} 

/** 
* Initialize the listeners and send the file if have. 
*/ 
function init() { 
    filesUpload = document.getElementById('input-files'); 
    filesUpload.addEventListener('change', fileHandler, false); 
} 

/** 
* Handle the file change event to send it content. 
* @param e 
*/ 
function fileHandler(e) { 
    var files = e.target.files || e.dataTransfer.files; 

    if (files) { 
     //send only the first one 
     file = files[0]; 
    } 
} 

function sendFile() { 
    if (file) { 
     //read the file content and prepare to send it 
     var reader = new FileReader(); 

     reader.onload = function(e) { 
      console.log('Sending file...'); 
      //get all content 
      var buffer = e.target.result; 
      //send the content via socket 
      socket.emit('send-file', file.name, buffer); 
     }; 
     reader.readAsBinaryString(file); 
    } 
} 

一些重要的注意事项:

这是一个小例子的socket文件上传器。我在这里不考虑一些重要的事情:文件块发送一块文件,而不是连续的所有内容;将发送文件的状态更新为(错误消息,成功消息,进度条或百分比阶段等)。所以这是一个示例,用于编写您自己的文件上传器的初始步骤。在这种情况下,我们不需要一个表单来发送文件,它是通过socket.io完全异步的事务。

我希望这篇文章有帮助。

+0

我已经找了一个解决方案,因为两天以上,这是第一个,工作!谢谢! – RedDot 2013-02-10 00:00:26

+0

很高兴看到该解决方案为您工作! – Ito 2013-02-10 07:11:21

0

这​​去一个远一点,因为你可以暂停/恢复上传,但你会发现如何上传通过socketio :)文件