简体   繁体   中英

Uploading mp3 to NodeJS Express server corrupts file

I would like to upload an MP3 file from my web client to a Node Express server. I can upload the file, then write it to disk. However, the file gets corrupted and I cannot play the song using an MP3 player.

If it makes a difference, the file is being uploaded from an OS X machine, then gets written to an Ubuntu server. The size of the uploaded of the uploaded file is larger than the original. I receive no errors in this workflow. Nothing goes wrong until I start to play the file.

Please see below for my code. Any ideas about why I'm experiencing this?

CLIENT

uploadSong: (song) => {
  fetch('http://localhost:8080/song', {
    method: 'PUT',
    headers: {
      'Content-Type': 'audio/mpeg',
    },
    body: song
  })
  .then( response => {
    console.log("Got response after uploading song:", response);
  })
  .catch( error => {
    console.log("Error in Firebase AC upload song: ", error);
  });
}

SERVER

app.put("/song", (req, res) => {
  var mp3SongName = 'test.mp3';
  var mp3_file = fs.createWriteStream(mp3SongName);

  mp3_file.on('open', function (fd) {
    req.on('data', function(data){
        console.log("loading... \n");
        mp3_file.write(data);
    }); 

    req.on('end', function(){
        console.log("finalizing...");
        mp3_file.end();
        res.sendStatus(200);
    });
  });
}

I noticed when inspecting the uploaded files that the data was getting written as a base64 encoded string.

I traced this back to my client code, which was using the FileReader.readAsDataUrl method to read the file:

...the result attribute contains the data as a URL representing the file's data as a base64 encoded string

Mystery solved. Now I just need to figure out whether to decode the file on the server, or use a FileReader method that doesn't encode this in the first place.

Use this code for file uploading. This is the server side code. I named it as server.js

var express = require('express');
var multer = require('multer');
var path = require('path');
var rand;
var app = express();
var ejs = require('ejs')
app.set('view engine', 'ejs')
var storage = multer.diskStorage({
    destination: function(req, file, callback) {
        callback(null, './public/uploads')
    },
    filename: function(req, file, callback) {
        //callback(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname))
                //callback(null, file.originalname)
        rand=Date.now() + path.extname(file.originalname);

        callback(null, file.fieldname + '-' + rand);

    }

})
var upload = multer({
        storage: storage});
app.get('/api/file',function(req,res){
res.sendfile('E:/syed ayesha/nodejs/uploads/video/views/video.html');
});
app.post('/api/file',upload.single('userFile'), function(req, res) {
    console.log(req.file);
    console.log(req.file.path);
    res.send(rand);

})
app.listen(3000,function(){
console.log("working on port 3000");
});

create a views folder and place this html file in it. I named as video.html

<form id="uploadForm"
      enctype="multipart/form-data"
      action="/api/file"
      method="post"
>
 <input type="file" name="userFile"/>
<input type="submit" value="Upload File" name="submit">

</form>

Run the server a node server.js . Open the browser and run this api http://localhost:3000/api/file and choose any file it may audio/video/pdf/image etc ..any file you want to upload to disk. In this code I am uploading my files to public/uploads in this root project folder. You can give your destination folder from where you want to store the uploaded files. Hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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