D
D
Danil Shitov2019-09-17 22:59:04
JavaScript
Danil Shitov, 2019-09-17 22:59:04

How to upload file to node.js server without 3rd party libraries?

How to upload file to node.js server without third party libraries? What happens to a file when it is uploaded via a form? What format does it take? And how to view the real contents of this file?
Here is the html code of the page where there is only input for uploading a file and a button for submitting the form

<!DOCTYPE HTML>
<html>
  <head>
    <meta charset="utf-8">
  </head>
  <body>
  <form id="file_load">
    <input type="file" name="myfile">
    <input type="submit" value="Загрузить">
  </form>
<script src="script.js"></script>
</body>
</html>

Here is the script.js file code which just sends the file from the form to the server:
file_load.onsubmit = function(){
  var file = this.elements.myfile.files[0];
  var xhr = new XMLHttpRequest();
  xhr.open("POST", "upload", true);
  xhr.send(file);
  return false;
}

And finally the backend code that receives and writes the file:
const server = require('http').createServer();
var  fs = require('fs');
var static = require('node-static');
var file = new static.Server('.', {
  cache: 0
});

server.listen(3000,()=> console.log("сервер запущен"));
server.on('request',(req,res)=>{
  if (req.url == '/upload') {
    var body = "";
    req.on('data', function(chunk) {
      body+=chunk;
    }).on('end',function(){
      fs.writeFileSync("file2.jpg",body);
      res.end('ok');
    })
  }else{
    file.serve(req, res);
  } 
});

All the code is working, and does its job well, but as it turns out, not a file is sent, but some kind of garbage, of an unknown format. If the file initially weighed 185 kb, then the uploaded one weighs 300 kb,
the first lines in the hex of the original file:
5d812c9421d0e918278273.png
and uploaded:
5d812d42c2299026715535.png
And I began to google hard, what happens to the file when it is loaded through the form, and how to deal with it. I didn’t really find anything, but I found out that the file can be read using the file api. I read the file using the reader.readAsText() method, I thought I would get the contents of the file using this, but nothing has changed, the file is sent in exactly the same format.
here is my modified code under file api script.js:
var reader = new FileReader();
file_load.onsubmit = function(){
  var file = this.elements.myfile.files[0];
  reader.readAsText(file);
  return false;
}
reader.onload = function(e) {
      file = e.target.result;                  
      upload(file);
}
function upload(file){
  var xhr = new XMLHttpRequest();
  xhr.open("POST", "upload", true);
  xhr.send(file);
}

Nothing has changed, the same file arrives

Answer the question

In order to leave comments, you need to log in

1 answer(s)
D
Dmitry Belyaev, 2019-09-17
@daniilshitov

In this case, the file is sent in the request body as is, without any wrappers:

file_load.onsubmit = function(){
  var file = this.elements.myfile.files[0];
  var xhr = new XMLHttpRequest();
  xhr.open("POST", "upload", true);
  xhr.send(file);
  return false;
}

Therefore, on the server, it is enough for us to redirect the entire request body to a file:
const server = require('http').createServer();
const fs = require('fs');
const nodeStatic = require('node-static');
const file = new nodeStatic.Server('.', {
  cache: 0
});

server.listen(3000, () => console.log("сервер запущен"));
server.on('request', (req, res) => {
  if (req.url == '/upload') {
    req.pipe(
      fs.createWriteStream('file2.jpg')
    ).on('finish', () => res.end('ok'));
    return;
  }
  file.serve(req, res);
});

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question