preface
- 【 Music Blog 】During registration, the avatar is uploaded to the server and koA is used as the background
Four aspects:
1. Upload files using the formidable library
-
var formidable = require('formidable') var form = new formidable.IncomingForm() form.uploadDir = uploadPath form.parse(ctx.req, function (err, fields, files) { console.log('files', files) // Throw an error when an error is reportedif(err) { throw err; } var ran=parseInt(math.random ()*89999+10000); // var extname=path.extname(files.appealFile.name); Var extName = files.appealfile.name; var extName = files.appealfile.name; // To change the path, change the path of the two variables const oldPath = __dirname +"/.. /" + files.appealFile.path; // console.log(oldPath); const newPath = __dirname + "/.. /audio/" + extname; // console.log(newPath); fs.rename(oldPath, newPath, (err) => { if (err) { console.log(err); throw Error('Name change failed'); } res.send(newPath).end("success"); })})Copy the code
- It turns out that none of the form.parse methods can get in, let alone the subsequent save operations
- Many methods have been tried and failed; Before using Node is no problem, but once to koA this can not enter, also will not report an error, unknown li
2. Upload files using koa-body
- Finally change a file upload method, using the form of stream to local
- Installation of koa – body
-
npm install koa-body --saveCopy the code
- Reference the KOA-body middleware in a KOA project
-
const koaBody = require('koa-body'); app.use(koaBody({ multipart: true, formidable: {maxFileSize: 200*1024*1024 // Set maximum file size limit, default 2M}}));Copy the code
-
With the KOA-body middleware, the uploaded files can be retrieved through ctx.request.files
Reminder: the new version of koa-body obtains uploaded files through ctx.request.body.files The old version of koA-body obtains uploaded files through ctx.request.body.files
-
After the file is obtained, the file is saved to the specified directory on the server through FS
-
Const uploadFile = (fileArr) => {var resultArr = [] filearr.foreach (Element => {// Prevent file names from being consistent, // const randomNum = math.floor ((math.random () * 9 + 1)*1000); const randomNum = new Date().getHours()+""+new Date().getMinutes(); // Create a stream const reader = fs.createreAdStream (Element [1].path);let filePath = path.join(__dirname, '.. /public/node/upload/image/user/') + `${randomNum}_${element[1].name}`; // let filePath = path.join(__dirname, '.. /public/upload/image/user/') + ` /${element[1].name}`; Const upStream = fs.createWritestream (filePath); // read. Pipe (upStream); resultArr.push({ fileName: element[1].name, filePath: filePath.replace(new RegExp(/(\\)/,"g"),'\ \ /'FileUrl: '/node/upload/image/user/${randomNum}_${element[1].name}', // give the front end a picture randomNum: randomNum})});return resultArr; }Copy the code
3. Front-end file upload (native)
- I can change the way I write it, but I’m using TS
- html
-
<form id="sendAppealForm"> <a href="javascript:void(0);" class="upload"> Select file > <span class="unfile"> No file is selected </span> <input class="replyFileid" name="appealFile" id="appealFile" type="file" multiple="multiple" /> </a> </form> <el-button type="danger" style="width:100%; margin-bottom:30px;" @click.native.prevent="handleRegiste"> {{$t('registe.registeIn') }}</el-button> </el-form>Copy the code
-
private handleRegiste() { var aaa: any = document.getElementById('sendAppealForm') var formData = new FormData(aaa); var myDate = new Date(); formData.append("uploadTime", myDate.toLocaleDateString()); Var _this = this; this.uploadFile(formData).then(res => { console.log(res); }); } private uploadFile = (param: any) => {return new Promise((resolve, reject) => { axios .post("http://localhost:3000/users/register", param, { headers: { "Content-Type": "multipart/form-data" } }) .then(res => { resolve(res.data); }) .catch(err => { reject(err.data); }); }); };Copy the code
4. Front-end upload file (Ele. me component Upload)
- Manually upload files, and can upload only a single file, and can overwrite the upload
- First on the code, the following analysis:
-
<el-upload class="avatar-uploader" action="/certificateAuthentication/upload" :http-request="imgUpload" accept=".png, .jpg, .gif, .jpeg" :show-file-list="false" ref="upload" :auto-upload="false" :on-change="handleChange" :before-upload="beforeAvatarUpload" > <img v-if="imageUrl" :src="imageUrl" class="avatar" /> <i v-else class="el-icon-plus avatar-uploader-icon"></i> </el-upload> <el-button type="danger" @click.native.prevent="handleRegiste"</el-form> </el-form>Copy the code
-
fileList = []; handleChange(file, fileList) { if(filelist.length > 0) {this.filelist = [fileList[filelist.length-1]] // This step is to display the last selected CSV file}} privatehandleRegiste() { (this.$refs.upload as any).submit(); } private async imgUpload(e: any) { const param = new FormData(); param.append("info", JSON.stringify(this.loginForm)); param.append("file", this.fileList); // e.file const data: any = await register(param); // console.log(data); if(data.result.length ! == 0) { this.$router.push({ path: "/login", query: {} }); this.$message({ message: "Registration successful".type: "success"}); }}Copy the code
- Because it is a registration function, I don’t want to click upload file to upload to the server, I need to click the registration button to upload information and pictures together, so I need to manually upload
- Upload component of Ele. me can be set to manual upload (automatic upload off)
-
:auto-upload="false"Copy the code
- It is then called in the registration button method
-
this.$refs.upload.submit(); Copy the code
- He’ll find the component’s http-Request =”imgUpload” property and call the imgUpload method
- Manual upload has been solved. Next, you can only upload a single file
- The file-list property holds an array of files selected by the user.
-
-
The on-change method is used to change the list of selected files in the file-list and keep only the last one.
-
Basic functions to achieve the target scene, but there is a question of style, because is that change file – the list, the last item, therefore, after the user to select the second file, from the first file to the second file, have the effect of the dynamic switch, this is not what I want, what I want is the user click the “upload document”, local files, choose a computer Click “OK” to display the selected file on the page without dynamic switching.
-
CSS removes this part of the animation
-
<style lang="scss" scoped> .upload-demo { display: flex; } /deep/ .el-list-enter-active, /deep/ .el-list-leave-active { transition: none; } /deep/ .el-list-enter, /deep/ .el-list-leave-active { opacity: 0; } /deep/ .el-upload-list { height: 40px; } </style>Copy the code
- As for what /deep/ does in CSS, it’s really about modifying the internal styles of third-party components like elementui. If SCSS is not used, you can use >>> symbols to modify the internal styles of third-party components.
- The perfect solution
The final summary
If you know how to use formidable by KOA, and why I can’t enter the form.parse method, please let me know in the comments section if you are convenient, thank you!
The original address
Juejin. Cn/post / 684490…
reference
NodeJs koa2 implementation file upload: www.jianshu.com/p/34d0e1a5a…
The pit of vue upload files: blog.csdn.net/fengtingYan…
Element UI implement manually uploading files, and can upload a single file, and can cover upload: www.cnblogs.com/lovemomo/p/…