在服务器上上传视频/图像(没有快递的Nodejs)

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

由于 AJAX,我正在尝试在 nodejs 服务器上上传视频,这是当前脚本:

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)
    }
})

这里的路由器只是我自己的模块,它创建了 HTTP 服务器和 matchURL 方法在 URL 正常时执行回调

问题是视频上传的很好,但我不能运行,好像文件已损坏...

非常感谢!

编辑:

这里有一个解决方案:https://nodejs.org/en/knowledge/HTTP/servers/how-to-handle-multipart-form-data/

事实上multipart/form-data公式可以包含破坏文件的边界。

所以,我们必须使用一个可以解析数据的模块(这里是强大

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

这是 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
                })
            })
        })
    }
})