jquery - 如何使用 multer(或其他)使用 jquery ajax 在 Nodejs 中上传文件?
问题描述
我有一个表单,它使用字符串/数字将 JSON 文件输出到后端。我也需要它将图像输出到后端并让 multer 进行实际上传。我可以轻松使用 multer,但不能在 ajax 中使用。e.preventDefault() 让我更难了,所以我请你看看我的代码并解释我做错了什么以及如何改进它。提前致谢 :)
//Form
<form action="/dashboard" method="POST" id="newproduct-form" class="row" enctype='multipart/form-data'>
<div class="form-row">
<div class="col">
<label>Product name</label>
<input type="text" class="form-control" id="product_name" placeholder="Product name" value="<%= typeof product_name !='undefined' ? product_name:'' %>">
<label>Price per unit</label>
<input type="text" class="form-control" id="price_PerUnit" placeholder="How many does one unit cost" value="<%= typeof price_PerUnit !='undefined' ? price_PerUnit:'' %>">
<input type="submit" id="submitNewProduct">
<a class="btn btn-success" id="backFormBTN">Back</a>
</div>
<div class="col">
<label>Product Description</label>
<input type="text" class="form-control" id="product_Description" placeholder="Brief description of the product" value="<%= typeof product_Description !='undefined' ? product_Description:'' %>">>
<label> Product Amount</label>
<input type="text" class="form-control" id="product_Amount" placeholder="How much do you have of this product" value="<%= typeof product_Amount !='undefined' ? product_Amount:'' %>">
<label>Product Image</label>
<input type="file" name="productImage" class="form-control-file">
<small id="fileHelp" class="form-text text-muted">This is some placeholder block-level help text for the above input. It's a bit lighter and easily wraps to a new line.</small>
</div>
</div>
</form>
//Ajax
$('#submitNewProduct').click((e) =>{
e.preventDefault();
productName = $('#product_name').val();
pricePerUnit = $('#price_PerUnit').val();
productDescp = $('#product_Description').val();
productAmount = $('#product_Amount').val();
//Front End validation
if(!productName || !pricePerUnit || !productDescp || !productAmount){
ajaxMessaging('red','Please fill all inputs');
}else if(isNaN(pricePerUnit) || isNaN(productAmount)){
event.stopImmediatePropagation();
ajaxMessaging('red','The Poduct Amount and Price per Unit fields should contain numbers only');
}else{
//Add new product
$.ajax({
type: 'POST',
url: '/dashboard',
data: JSON.stringify({
product_name : productName,
price_PerUnit : pricePerUnit,
product_Description : productDescp,
product_Amount: productAmount,
}),
contentType: 'application/json',
success: ajaxMessaging('green', 'Submited')
});
}
});
//Backend using Nodejs and express engine
router.post('/dashboard', (req, res) => {
upload(req,res,(err) =>{
if(err) console.log(err);
console.log(req.file);
});
const{product_name, price_PerUnit, product_Description, product_Amount} = req.body;
var errors = [];
//Check required fields
if(!product_name || !price_PerUnit || !product_Description || !product_Amount){
errors.push({msg : "Enter all fields"});
console.log(product_name);
}
if(errors.length > 0){
res.render('dashboard', {
product_name,
price_PerUnit,
product_Description,
product_Amount,
errors,
});
req.flash('error_msg', 'Please fill all the fields');
}else{
//Finds the current user and pushes value into product array
User.findOneAndUpdate(
{ email : useremail }, //Find collection with same email as user
{ $push: { products: {
productName :product_name,
productDescription : product_Description,
pricePerUnit : price_PerUnit,
productAmount : product_Amount,
} } },
(err) => {
if (err) throw console.log('found errors');
req.flash('success_msg', 'New record');
errors.push({msg : "New record in the database"});
})
console.log('Succesfuly uploaded new product');
}
解决方案
您应该在路由上将 Multer 作为中间件传递,然后req.body.FIELD_NAME
在控制器函数中将其返回。您可以传递单个字段或数组,例如:
const multer = require('multer');
router.post('/dashboard', upload.single('cover', 1), upload.array('photos', 4), (req, res) => {
const data = {
cover: req.body.cover,
photos: req.body.photos
}
console.log(data);
}
此外,首先,您可以将一些配置传递给它,以便更好地处理 mime 类型、文件存储等:
// Config multer for using inside upload middleware
const imgStorage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'public/static/uploads')
},
filename: (req, file, cb) => {
const fileExt = file.mimetype.split('/');
// randomStringGenerator is my helper function to generate random strings with custom number of characters :)
cb(null, file.fieldname + randomStringGenerator(50) + '.' + fileExt[1])
}
});
// Create an image filter
const imgfileFilter = (req, file, cb) => {
if (file.mimetype === 'image/jpeg' || file.mimetype === 'image/png') {
cb(null, true);
} else {
cb(null, false);
}
}
// Create an upload middleware
const upload = multer({
storage: imgStorage,
fileFilter: imgfileFilter,
limits: {
fieldSize: 1024 * 1024 * 2
}
});
推荐阅读
- java - Quartz 中的 Job 和 JobDetail 有什么区别?
- docker - GitLab CI/CD:构建多架构 Docker 镜像
- npm - 使用 npm 响应安装问题
- python - 使用 uwsgi 运行时无法访问 .env 文件
- laravel - Laravel 网络套接字错误
- ansible - 如何检查 PID 是否在 ansible 中运行,如果没有,则任务失败?
- c# - C# asp,net 项目正在 IDE 上运行,但在 IIS 上部署后出现错误
- ruby-on-rails - Rails redirect_to @service 在非开发环境中重定向到本地主机
- python - 在python中计算倾向函数
- java - 如何覆盖 TreeMap 的比较器