Javascript 完全控制nodejs中使用ajax发送的文件
我使用Javascript 完全控制nodejs中使用ajax发送的文件,javascript,node.js,multer,Javascript,Node.js,Multer,我使用multer解析以multipart/data form形式发送的多个文件,使用axios ... const storage = multer.diskStorage({ destination: './gallery', filename(req, file, cb) { (1) .... }, }); const upload = multer({ storage }); router.post('/products', upload.arr
multer
解析以multipart/data form
形式发送的多个文件,使用axios
...
const storage = multer.diskStorage({
destination: './gallery',
filename(req, file, cb) {
(1) ....
},
});
const upload = multer({ storage });
router.post('/products', upload.array('images'), (req, res, next) => {
Product.create(...)
.then((product) => {
(2) ...
})
.catch(..)
})
...
在这一点上,一切都很好,我的图像被保存
问题是我想在(1)或(2)中做一个循环,并这样命名我的文件
files.forEach((file, index) => {
// rename file to => product_id + '_' + index + '.jpeg'
}
例如,如果我有3个文件,它们将被命名为
5a9e881c3ebb4e1bd8911126_1.jpeg
5a9e881c3ebb4e1bd8911126_2.jpeg
5a9e881c3ebb4e1bd8911126_3.jpeg
其中5a9e881c3ebb4e1bd8911126是mongoose
保存的产品文档的id
如何解决这个命名问题
multer
是我想要完全控制文件的最佳解决方案吗李>
使用另一个节点包是否有更好的方法
以多部分/数据表单
或数据URL base64
的形式发送图像好吗
您不能仅在(1)
中设置名称,因为此时您还不知道产品的ID
您不能仅在(2)
中设置名称,因为此时文件已经保存(使用文件名(req,file,cb)
函数生成的文件名)
因此,我认为最好的解决方案可能是在上传文件后移动它们
这可以在(2)
中完成。当您在路由器中处理文件时,req.files
将是一组已上载的文件
在Product.create
的承诺回调中,您可以访问该产品(您需要该ID)和文件列表(您需要该编号)
为此,可以使用fs.rename(oldPath、newPath、callback)
像这样的方法应该会奏效:
Product.create(...).then((product) => {
req.files.forEach((file, index) => {
// file.path is the full path to the file that was uploaded.
// newPath is where you want to put it.
// Let's use the same destination and just change the filename.
const newPath = file.destination + product.id + '_' + index
fs.rename(file.path, newPath)
})
})
这很容易,只要您了解express的工作原理。因此,在开始解决问题之前,有一个清晰的理解是很重要的
当您有下面这样的快速代码时
router.post('/abc', function(req, res) {res.send('hello world');})
const storage = multer.diskStorage({
destination: './gallery',
filename: (req, file, cb) => {
req.file_id = req.file_id || 0;
req.file_id++;
console.log('Product id - ' + req.product_id);
cb(null, req.product_id +'_' + req.file_id +'.js');
},
});
Express传递来自多个中间件/功能链的请求。现在,每个函数获得req、res、next
参数。下一个是函数,假设中间件在处理完成时调用该函数。如果中间件决定不调用next
,则请求在此结束,不再调用更多的中间件
当我们使用function(req,res){res.send('hello world');}
时,我们根本没有使用next
参数,这意味着我们对任何其他代码都不感兴趣。现在回到我们的问题上来
router.post('/products', upload.array('images'), (req, res, next) => {...}
您首先使用了upload.array('images')
,然后使用了实际的产品创建
code。所以我将展示两种方法来解决这个问题
再多一个中间件来重命名文件
router.post('/products',upload.array('images'),(req,res,next)=>{
颠倒处理顺序
在这种方法中,您首先创建产品,然后进行图像处理
let express = require('express');
let bodyParser = require('body-parser');
app = express();
let multer = require('multer');
const storage = multer.diskStorage({
destination: './gallery',
filename: (req, file, cb) => {
console.log('Product id - ' + req.product_id);
cb(null, req.product_id + '.js');
},
});
const upload = multer({ storage });
app.all('/', (req, res, next) => {
console.log('Hello you');
promise = new Promise((resolve) => {
// simulate a async product creation
setTimeout(() => resolve(1234), 100);
});
promise.then((product_id) => {
console.log('create the product and get the new product id')
// set the product id in the request object, so the multer
// filename function can access it
req.product_id = product_id;
res.send('uploaded files');
if (next)
next();
});
}, upload.array('images'));
module.exports = {
app
};
app.listen(8020);
用邮递员测试也很好
编辑:2018年3月19日
对于多个文件,您可以轻松地更新文件名函数代码,如下所示
router.post('/abc', function(req, res) {res.send('hello world');})
const storage = multer.diskStorage({
destination: './gallery',
filename: (req, file, cb) => {
req.file_id = req.file_id || 0;
req.file_id++;
console.log('Product id - ' + req.product_id);
cb(null, req.product_id +'_' + req.file_id +'.js');
},
});
这将确保您获得该产品的所有文件。现在来回答您的问题
如何解决此命名问题?
这个答案已经做到了
multer是否是最好的解决方案,因为我希望完全控制我的文件?
我不能说,只要它起作用,做你想做的事,它就应该足够好了
使用另一个节点包是否有更好的方法?
我找不到很多软件包。但是如果你想的话,你可以去探索
以多部分/数据表单或数据URL base64的形式发送图像好吗?
我会使用multipart/data form
,这样客户端就不需要base64转换。但这也是一个意见问题。multer只是一个临时保存multipart/form数据的解决方案。
。最佳实践是使用您自己的逻辑操作临时数据(上传到云端,更改文件名,使用您自己的id进行散列,并将id存储在数据库中,等等)。@gokc以及如何使用我自己的逻辑操作数据而不使用multer
?谢谢男士:)在反转处理顺序
方法中,仅保存最后一个文件,因为单个产品id
将有多个文件,我可以通过指定类似新日期()的内容来解决此问题。getTime()
@Youssef,请查看回答末尾的最新编辑谢谢男士:)你能回答我问题中的其他几点吗?