This is the 20th day of my participation in the November Gwen Challenge. Check out the details: The last Gwen Challenge 2021
The realization of upload function
- Set the type of the upload form to File.
Note: The name attribute is indispensable.
<li> food image: <input type="file" name="picUrl" /></li>
Copy the code
- Configure the mode for uploading files
// Configure the mode for uploading files
config.multipart = {
mode: 'file'
};
Copy the code
- Configure CSRF attributes
The encType attribute is indispensable.
<form action="/<%=adminPath%>/product/doAdd? _csrf=<%=csrf%>" method="post" enctype="multipart/form-data">
Copy the code
- Set the route to POST
router.post(` /${config.adminPath}/product/doAdd`,controller.admin.product.doAdd);
Copy the code
- File is read from the controller
async doAdd() {
const {ctx} = this;
const body = ctx.request.body;
const file = ctx.request.files[0];
ctx.body = {
body: body,
file: file
}
}
Copy the code
Saves the uploaded file in the specified location
- Installing the Tool Package
npm i mz mz-modules --save
Copy the code
- Introduce toolkits into the controller
const path = require('path');
const fs = require('mz/fs');
const pump = require('mz-modules/pump');
Copy the code
- Create a folder to upload to, this folder should be created in advance (public/upload)
- Controller read and write logic implementation
async doAdd() {
const {ctx} = this;
const body = ctx.request.body;
const file = ctx.request.files[0];
// Get the file name
const filename = file.filename;
const targetPath = path.join('app/public/upload',filename);
// Read the file
const source = fs.createReadStream(file.filepath);
// Create a write stream
const target = fs.createWriteStream(targetPath);
try {
await pump(source,target);
} finally {
await ctx.cleanupRequestFiles();
}
ctx.body = "Write succeeded"
}
Copy the code
Realize multiple file upload
- Static page Settings are as follows:
- The core implementation logic of the controller
// Implement multiple file uploads
async doAdd() {
const { ctx } = this;
const body = ctx.request.body;
const files = ctx.request.files;
try {
for (let file of files) {
const filename = file.filename;
const targetPath = path.join('app/public/upload', filename);
// Read the file
const source = fs.createReadStream(file.filepath);
// Create a write stream
const target = fs.createWriteStream(targetPath);
awaitpump(source,target); }}finally {
await ctx.cleanupRequestFiles();
}
ctx.body = {
body, files
}
}
Copy the code
Upload pictures by date folder
Here’s what it looks like:
- Introduce toolkits into services
const sd = require('silly-datetime');
const path = require('path');
const mkdirp = require('mz-modules/mkdirp');
Copy the code
- Define the upload path in the configuration file
// Set a path for uploading images
config.uploadDir = "app/public/upload";
Copy the code
- Define functions to create paths and folders in the service
async getUploadFile(filename) {
// Get the current date
let day = sd.format(new Date(),'YYYYMMDD');
// Create a path to save the image
let dir = path.join(this.config.uploadDir,day);
await mkdirp(dir);
// Generate the file name
let unix = this.getUnixTime();
let saveDir = path.join(dir,unix + path.extname(filename));
return saveDir;
}
Copy the code
- Asynchronously call the file path in the controller
const targetPath = await this.ctx.service.tools.getUploadFile(filename);
Copy the code
Below is the appendix for all the controller code
async doAdd() {
const { ctx } = this;
const body = ctx.request.body;
const files = ctx.request.files;
try {
for (let file of files) {
const filename = file.filename;
// const targetPath = path.join('app/public/upload', filename);
const targetPath = await this.ctx.service.tools.getUploadFile(filename);
// Read the file
const source = fs.createReadStream(file.filepath);
// Create a write stream
const target = fs.createWriteStream(targetPath);
awaitpump(source,target); }}finally {
await ctx.cleanupRequestFiles();
}
ctx.body = {
body, files
}
}
Copy the code