简体   繁体   中英

Upload video / image on a server (Nodejs without express)

I'm trying to upload a video on a nodejs server thanks to AJAX, here is the current script:

home.ejs:

    <form action="#" method="post" enctype="multipart/form-data">
        <input type="file" name="file" class="file" />
        <input class="submit" type="submit" value="Send" />
    </form>

    <script>
        let form = document.querySelector("form")
        let file = document.querySelector(".file")

        form.addEventListener("submit", e => {
            e.preventDefault()
            let reader = new FileReader();
            reader.onload = function(evt) {
                let xhr = new XMLHttpRequest()
                xhr.open("POST", "/server", true)
                xhr.send(evt.target.result)
            }
            reader.readAsBinaryString(file.files[0])
        })
    </script>

server.js:

router.matchURL("/server", (req, res, data) => {
    if (req.method === "POST") {
        let writer = fs.createWriteStream("../test.mp4")
        req.pipe(writer)
    }
})

Here router is just my own module who create the HTTP server and the matchURL method execute the callback if the URL is good

The problem is that the video is well uploaded but I can't run it, like if the file was corrupted...

Thanks a lot !

EDIT:

  • This code works with a txt file, so I don't know where come the problem, maybe the encoding (Even if I tried to change the write encoding to binary and it not worked), I also tried to use an ArrayBuffer but it doesn't worked !

  • I also tried to upload a 1px * 1px image (So it only take 1 chunk) but it also doesn't work. So the problem is maybe a lose of data but I don't know how to solve it. I noticed a change between original image and the uploaded image: The original image size is 802o and the uploaded image size is 998o, but this kind of changes doesn't appear on txt files

There is a solution here: https://nodejs.org/en/knowledge/HTTP/servers/how-to-handle-multipart-form-data/

In fact multipart/form-data formular can contains boundary which corrupt the file.

So, we have to use a module which can parse the data (Here it's formidable )

formidable link: https://www.npmjs.com/package/formidable

Here is the solution with AJAX:

home.ejs :

<form action="#" method="post" enctype="multipart/form-data">
    <input type="file" name="file" class="file" />
    <input class="submit" type="submit" value="Send" />
</form>

<script>
    let form = document.querySelector("form")
    let fileInput = document.querySelector(".file")

    form.addEventListener("submit", e => {
        e.preventDefault()
        let xhr = new XMLHttpRequest()
        let formData = new FormData(form)
        xhr.open("POST", "/upload", true)
        xhr.send(formData)
    })
</script>

The FormData interface provides a way to easily construct a set of key/value pairs representing form fields and their values, which can then be easily sent using the XMLHttpRequest.send() method ( https://developer.mozilla.org/en-US/docs/Web/API/FormData )

// Function which execute the callback if /upload is called
const formidable = require("formidable")

// Execute the callback if the URL is requested
router.matchURL("/upload", (req, res, data) => {
    if (req.method === "POST") {
        let form = new formidable.IncomingForm()

        // We parse the request to get fields and files
        form.parse(req, (err, fields, files) => {
            if (err) throw err

            res.writeHead(200, {'content-type': 'text/plain'});

            // We write the copy of the video using the path of the temp video file
            let writer = fs.createWriteStream("../video.mp4")
            let reader = fs.createReadStream(files.file.path).pipe(writer)
            writer.on("finish", () => {
                // Once the video uploaded, we delete the temp file
                fs.unlink(files.file.path, err => {
                    if (err) throw err
                })
            })
        })
    }
})

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