简体   繁体   English

使用Websockets和Nodejs上载文件

[英]Upload Files with Websockets and Nodejs

I'm trying to implement a file uploader, where a HTML input file is sent by a WebSocket to a Nodejs server. 我正在尝试实现一个文件上传器,其中一个HTML输入文件由WebSocket发送到Nodejs服务器。

Tried to read the file in a BLOB and binary string from the FileReader API of HTML and sent it to Nodejs server so it can be written to a file in the server. 试图从HTML的FileReader API读取BLOB和二进制字符串中的文件,并将其发送到Nodejs服务器,以便将其写入服务器中的文件。 Tried createWriteStream and writeFile with ascii or base 64 encoding in the Nodejs part. 在Nodejs部分中尝试使用ascii或base 64编码的createWriteStream和writeFile。

Still the file saved in server doesn't work properly. 保存在服务器中的文件仍然无法正常工作。

Am I missing something? 我错过了什么吗?

Thank you 谢谢

UPDATE UPDATE

Client 客户

    var uploader = $("#uploader"),
        files = uploader.prop('files'),
        file_reader = new FileReader();
    file_reader.onload = function(evt) {
        socketClient.write({
            'action': 'ExtensionSettings->upload', 
            'domain': structureUser.domain, 
            'v_id': ext, 
            'file': file_reader.result
        });
    };
    file_reader.readAsDataURL(files[0]);
    //readAsDataURL
    uploader.replaceWith(uploader.clone());

Server 服务器

var stream = fs.createWriteStream("file");
stream.once("open", function() {
    stream.write(msg.file, "base64");
    stream.on('finish', function() {
        stream.close();
    });
});

.readAsDataURL()返回格式为data的字符串:MIMEtype; base64,....你应该在逗号之前删除part,因为它不是base64编码文件的一部分,它是服务数据

Consider starting a separate http server on a different port being used by the websocket and then upload the file via traditional post action in a form. 考虑在websocket使用的不同端口上启动单独的http服务器,然后通过表单中的传统post操作上传文件。 Returning status code 204 (no content) ensures the browser doesn't hang after the post action. 返回状态代码204(无内容)可确保浏览器在发布操作后不会挂起。 The server code assumes directory 'upload' already exists. 服务器代码假定目录“upload”已存在。 This worked for me: 这对我有用:

Client 客户

<form method="post" enctype="multipart/form-data" action="http://localhost:8080/fileupload">
    <input name="filename" type="file">
    <input type="submit">
</form>

Server 服务器

http = require('http');
formidable = require('formidable');
fs = require('fs');

http.createServer(function (req, res) {

    if (req.url === '/fileupload') {

        var form = new formidable.IncomingForm();
        form.parse(req, function (err, fields, files) {
            var prevpath = files.filename.path;
            var name = files.filename.name;
            var newpath = './upload/' + name;

            var is = fs.createReadStream(prevpath);
            var os = fs.createWriteStream(newpath);

                // more robust than using fs.rename
                // allows moving across different mounted filesystems
            is.pipe(os);

                // removes the temporary file originally 
                // created by the post action
            is.on('end',function() {
                fs.unlinkSync(prevpath);
            });

                // prevents browser from hanging, assuming
                // success status/processing
                // is handled by websocket based server code
            res.statusCode = 204;
            res.end();

        });

    }

})
.listen (8080);

When you stream data in nodejs you do not use write() but instead use pipe(). 在nodejs中流式传输数据时,不使用write(),而是使用pipe()。 So once you have your write stream as you did: var stream = fs.createWriteStream("file"); 所以,一旦你有了你的写流:var stream = fs.createWriteStream(“file”); then you pipe() to it as in: sourcestream.pipe(stream); 然后你管道()到它:sourcestream.pipe(stream); But since the file is being transferred over the internet, your file will be sent in packets and so it will not arrive all at once but instead in pieces, you have to use a buffer array and manually count the data chunks. 但由于文件是通过互联网传输的,因此您的文件将以数据包形式发送,因此它不会一次性到达,而是分成几部分,您必须使用缓冲区数组并手动计算数据块。

You can learn the details here: http://code.tutsplus.com/tutorials/how-to-create-a-resumable-video-uploade-in-node-js--net-25445 您可以在此处了解详细信息: http//code.tutsplus.com/tutorials/how-to-create-a-resumable-video-uploade-in-node-js--net-25445

There is a module available too that is very easy to use and probably what you want: https://github.com/nkzawa/socket.io-stream 还有一个非常容易使用的模块,可能你想要的: https//github.com/nkzawa/socket.io-stream

If you didn't care necessarily about going over the socket, you can also do it within your client scripts with an ajax form POST using the formidable module on the server to process the form upload: https://github.com/felixge/node-formidable 如果您不必关心遍历套接字,您也可以使用服务器上的强大模块使用ajax表单POST在客户端脚本中执行此操作以处理表单上载: https//github.com/felixge/节点厉害

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM