如何将图像上传到 ExpressJS 服务器



我觉得我在试图解决这个问题时失去了理智。我是一个相当新的Web开发人员(这就像我的第三个真实项目(,我正在尝试创建一个具有图像上传功能的单页应用程序。我一直在使用 AJAX 进行前端/后端通信,所以我的第一个问题是是否可以使用 AJAX 发送图像?我听到有些人说是,有些人说不是,没有关于为什么,或者如果是,如何的细节。

我一直在寻找其他方法来做到这一点,但发现实际上包含足够细节/上下文来实现的方法很少。我已经设法使用基本的 HTML 表单和 multer npm 包在技术上工作的东西,如下所示:

editModal.innerHTML =   "<img class='thumbnail' src='" + response[0].image_loc + "'><br>" +
"<form method='post' action='/upload' enctype='multipart/form-data' id='edit_post_form'>" +
"   Select a new thumbnail<input type='file' id='post_thumbnail' name='file'><br>" +
"   Title<input type='text' id='post_title' name='title' value='" + response[0].title + "'><br>" +
"   Description<input type='text' id='post_desc' name='description' value='" + response[0].description + "'><br>" +
"   Price<input type='text' id='post_price' name='price' value='" + response[0].price + "'><br>" +
"   <button type='submit' class='submit' id='submit_post_edit'>Submit</button>" +
"   <button type='button' class='cancel' id='cancel_post_edit'>Cancel</button>" +
"</form>";
app.post('/upload', upload.single("file"), function(req, res) {
const tempPath = req.file.path;
const targetPath = path.join(__dirname, "./Assets/Images/image.png");
console.log(req.file);
if (path.extname(req.file.originalname).toLowerCase() === "png"
|| path.extname(req.file.originalname).toLowerCase() === "jpg") {
fs.rename(tempPath, targetPath, function(err) {
if (err) res.status(400).send({status: "Failure Internal server error"});
else res.status(200).send({status: "Success"});
});
}
else {
fs.unlink(tempPath, function(err) {
if (err) res.status(400).send({status: "Failure Internal server error"});
else res.status(403).send({status: "Failure Internal server error"});
})
}
})

问题在于,可以预见的是,此实现会将用户从页面重定向到要返回的 JSON 文件。有什么办法吗?我看到有人建议编写一个返回false的.onsubmit函数,并使用某种JQuery在该函数中发送文件。我有一个 .onsubmit 函数,我用它来将文本字段直接发送到数据库,我尝试从中返回 false,但它仍然重定向,所以我也觉得卡在那里。

form.onsubmit = function() {
var title = document.getElementById("post_title").value;
var description = document.getElementById("post_desc").value;
var price = document.getElementById("post_price").value;
$.ajax({
url: "DBRequest",
type: "POST",
async: false,
data: { data:
JSON.stringify(
{ query: "UPDATE post SET title = $1, description = $2, price = $3 WHERE pid = $4",
vars: [title, description, price, postID],
type: "update"})}
}).done(function(response) {
document.body.removeChild(document.getElementById("post_edit_modal"));
populate();
});
return false;
}

如果这两个问题的答案都是否定的,那么通常如何做到这一点?有没有地方可以详细阅读这个过程是如何工作的?这似乎很常见。

我认为这就是你要找的。防止表单重新加载页面或将您带到任何地方。

好的,对于遇到此问题的其他任何人,这是我设法使用 AJAX 组合在一起的通用解决方案:

.HTML:

<input type='file' id='file' name='file'>
<button type='button' class='submit' id='submit'>Submit</button>

客户端 JS:

submit = document.getElementById("submit");
submit.onclick = function() {
var fileData = $("#file").prop("files")[0];
var formData = new FormData;
formData.append("file", fileData);
$.ajax({
url: "upload",
dataType: "text",
cache: false,
contentType: false,
processData: false,
data: formData,
type: "POST",
}).done(function(response) {
//Handle success
}).catch(function(err) {
//Handle error
});
}

服务器端 JS:

let multer = require("multer");
const upload = multer({ dest: "/Images" });
app.post('/upload', upload.single("file"), function(req, res) {
const tempPath = req.file.path;
const targetPath = path.join(__dirname, "./Assets/Images/" + req.file.originalname);
if (path.extname(req.file.originalname).toLowerCase() === ".png"
|| path.extname(req.file.originalname).toLowerCase() === ".jpg") {
fs.rename(tempPath, targetPath, function(err) {
if (err) res.status(400).send({status: "Failure: Internal server error"});
else res.status(200).send({status: "Success"});
});
}
else {
fs.unlink(tempPath, function(err) {
if (err) res.status(400).send({status: "Failure: Internal server error"});
else res.status(403).send({status: "Failure: Internal server error"});
})
}
})

如果文件是 jpg 或 png,这会将单个文件上传到资产/图像。

最新更新