使用nodejs,expressjs和socket.io保存图像

时间:2013-02-09 13:56:41

标签: node.js express socket.io

我尝试使用express.js和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
    });

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

2 个答案:

答案 0 :(得分:8)

我做了一个简单的例子来说明通过套接字上传文件的用法!

以下步骤为:

  1. 创建发送文件 socket.io事件以在app.js上接收文件。收到的这个文件是二进制文件;
  2. 在jade / HTML页面中输入一个输入文件和一个按钮来发送它。注意:您不必使用multipart发送包含多部分内容的帖子,我们发送套接字文件而不是TCP请求/响应;
  3. 初始化HTML5文件API支持并准备听众观察文件输入组件;
  4. 剩余的例程,用于读取文件并向前发送内容。
  5. 现在第一步(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!');
                    });
                })
            });
    
        });
    });
    

    第二步(在我的情况下,我使用了jade而不是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')
    

    第三步和第四步(编码uploader.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.io完全异步的事务。

    我希望这篇文章有用。

答案 1 :(得分:0)

tutorial更进一步,因为您可以暂停/恢复上传,但您会发现如何通过socketio上传文件:)