在服务器上上传视频/图像(没有快递的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 正常时执行回调
问题是视频上传的很好,但我不能运行,好像文件已损坏...
非常感谢!
编辑:
此代码适用于 txt 文件,所以我不知道问题出在哪里,也许是编码(即使我尝试将写入编码更改为二进制但它不起作用),我也尝试过使用 ArrayBuffer 但它不起作用!
我也试过上传一张1px * 1px的图片(所以只需要1个chunk)但是还是不行。所以问题可能是数据丢失,但我不知道如何解决。我注意到原始图像和上传图像之间的变化:原始图像尺寸为 802o,上传图像尺寸为 998o,但这种变化不会出现在 txt 文件中
这里有一个解决方案: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
})
})
})
}
})
由于 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 正常时执行回调
问题是视频上传的很好,但我不能运行,好像文件已损坏...
非常感谢!
编辑:
此代码适用于 txt 文件,所以我不知道问题出在哪里,也许是编码(即使我尝试将写入编码更改为二进制但它不起作用),我也尝试过使用 ArrayBuffer 但它不起作用!
我也试过上传一张1px * 1px的图片(所以只需要1个chunk)但是还是不行。所以问题可能是数据丢失,但我不知道如何解决。我注意到原始图像和上传图像之间的变化:原始图像尺寸为 802o,上传图像尺寸为 998o,但这种变化不会出现在 txt 文件中
这里有一个解决方案: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
})
})
})
}
})