10

I'm using reader.readAsArrayBuffer() to send a file to node.js so that i can save it in a /public folder.

reader.readAsArrayBuffer(event.currentTarget.files[0])

When the read is done it calls a Meteor.method()

            reader.addEventListener("loadend", function(evt){

                Meteor.call("saveFile", reader.result)

            })

The meteor method receives a file and saves it to my public/folder.

      saveFile:function(file){

            var fs = Npm.require("fs")

            fs.writeFile('../../../../../public/logo/jow.png', file, {encoding:"binary"}, function (err) {

                console.log(err)
                console.log("file saved")

            });

        }

However, the problem is that i never get the encoding right, and when opening the file in /public/logo/jow.png i get this message:

jow.png can not be read, it may be damaged.

But when i change readAsArrayBuffer() to readAsBinaryString() it works as expected and i can open the image.

Any ideas?

mscdex
  • 104,356
  • 15
  • 192
  • 153
kevinius
  • 4,232
  • 7
  • 48
  • 79
  • Any update on this? I read on MDN that readAsBinaryString is deprecated. Has it been working for you? – chris May 22 '15 at 17:37
  • @helloChris i ended up using a buffer in my meteor methods (var buffer = new Buffer(file.length)) ... then for each file (buffer.writeUInt8(file) ... then (fs.writeFile(path + buffer)) ... so call the meteor method with (var byteArray = new Uint8Array(reader.result)) ..; Meteor.call("saveFile", byteArray) – kevinius May 26 '15 at 12:41
  • This is not a reproducible problem. Both methods produce the same result and there is no difference. It can be some another mistake in OP's code. – Andremoniy Nov 09 '17 at 11:17
  • How come there is no answer here? The deprecated method, how to use other method such as `readAsArrayBuffer()` – Mr Hery Apr 08 '18 at 02:30
  • In my mobile app to save/read image file I use combinations of FileReader and Blob. You can save base64 image string to blob, and read this blob with FileReader readAsArrayBuffer. I didn't have any problems using it. Blob in node.js try to replace with [this](https://stackoverflow.com/a/14737423/6345056) – JanuszO Mar 29 '20 at 09:19

1 Answers1

1

Is because readAsArrayBuffer sends the info in binary data (blob).

And if you view de docs in nodejs Buffers and character encodings the binary encoding is an alias of a latin1 encoding.

I don't know about meteor but if the file is a Buffer you can send it as is.

Example:

<body>
    <input type="file" />
    <button onclick="sendFile();">sendFile</button>
    <script>
        const sendFile = async () => {
            const reader = new FileReader();
            const file = document.querySelector('input[type=file]').files[0];

            reader.onloadend = function () {
                var xmlHttpRequest = new XMLHttpRequest();
                xmlHttpRequest.open("POST", 'http:/localhost:1234/', true);
                xmlHttpRequest.setRequestHeader("Content-Type", file.type);
                xmlHttpRequest.send(reader.result);
            }

            reader.readAsArrayBuffer(file);
        };
    </script>
</body>
const http = require("http");
const fs = require("fs");

http.createServer((req, res) => {
    if (req.method === "OPTIONS") {
        res.setHeader('Access-Control-Allow-Origin', '*');
        res.setHeader('Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, OPTIONS');
        res.setHeader('Access-Control-Allow-Headers', '*');
        res.writeHead(200, { });
        res.end();
        return;
    }

    if (req.method === "POST") {
        const data = [];
        req.on('data', chunk => {
            data.push(chunk);
        });
        req.on('end', () => {
            fs.writeFileSync(__dirname + "/file.png", Buffer.concat(data));
            res.writeHead(200, { });
            res.end();
        });
        return;
    }
}).listen(1234);

I send a PNG file and open it with any problem.

jtwalters
  • 1,024
  • 7
  • 25