山地人

第009期.关于上传组件的那点事

山地人
山地人
2021-05-13

img

img

进化岛的岛民们真的很勤奋好学,一大早就看到了小一同学给我的留言。希望可以讲讲文件上传方面的知识。好几个同学也纷纷表达了想要学习这块内容的想法。

所以,我们这一期的内容就专门来聊聊上传组件里的那点事。

这一期,自己会先封装原生的上传组件,搞清楚原生上传组件的原理。然后再结合vue+element,来看看第三方库中的upload组件又是如何使用。

自动动手写原生上传组件

我们通过一个非常简单的例子来看,文件上传这个功能的实现

上传组件——前端部分

对于前端,如果不用任何第三方库,上传部分的代码就下面这几行。

<!-- index.html -->
<form action="/upload" method="POST" enctype="multipart/form-data">
<input type='file' name='fileUploaded'>
<input type="submit" value="提交">
</form>

对于前端来说,上传一个文件需要哪些兵器配合

  1. 首先你需要一个表单,也就是上面代码里的<form>标签
  2. 告诉服务器你本地提交的表单发送到那个URL去处理,比如我们这里的/upload这个API来处理
  3. 上传文件走的是post请求,所以你需要用 method=“POST”方式提交数据
  4. 上传文件时,还需要指定MIME类型为multipart/form-data。如果不设置enctype,默认的POST请求MIME类型是application/x-www-urlencoded。这样我们的服务器就无法按照文件类型来接收到用户提交的数据了。
  5. 设定好form表单后,接下来需要在内部放入type类型为file的input标签,别忘了给这个input标签设置一个name。这个 <input type='file' name='fileUploaded'>就是用来存放我们要提交的文件的信息用的。
  6. 添加一个submit的提交按钮。

上面这些就是我们的原生上传组件的全部核心,到此,我们前端的任务就介绍了。

下面我们再来看看,对于后台,需要做哪些操作配置。

上传组件——后端部分

这里我们用Express来搭建一个简单的后台。

我们需要到到的第三方库:express, connect-busboy, fs-extra 。

#先初始化我们的package.json工程
npm init -y
#安装上面三个依赖
npm install -S express connect-busboy fs-extra

然后在我们的server.js顶部导入这几个第三方库

var express = require('express');
var busboy = require('connect-busboy'); //middleware for form/file upload
var path = require('path');
var fs = require('fs-extra');

配置一个最简单的express后台

var app = express();
//让busboy来解析浏览器请求的数据
app.use(busboy());
//配置public目录为静态资源目录
app.use(express.static('public'));
//这里一会要放入我们的上传相关的代码
//TODO...
var server = app.listen(3000, function() {
console.log('监听端口:%d', server.address().port);
});

上面这些就搭建了一个简单的serve,把我们上面创建的index.html文件放到public目录

下面是处上传请求的业务代码

//处理上传请求
app.post('/upload',function (req, res, next) {
var fstream;
req.pipe(req.busboy);
req.busboy.on('file', function (fieldname, file, filename) {
console.log("正在上传: " + filename);
fstream = fs.createWriteStream(__dirname + '/img/' + filename);
file.pipe(fstream);
fstream.on('close', function () {
console.log("上传成功:" + filename);
res.redirect('success');
});
});
});
//文件上传成功后,跳转到/success
app.get('/success',function(req,res,next){
res.send("<h1>上传成功</h1><a href='/'>返回</a>");
});

后台”/upload”的API收到客户端发来的文件上传请求后,使用pipe管道把获得的文件保存到服务器img目录下,完成后,重定向到success。此时,客户端会显示上传成功。

具体的演示代码,查看 009.file_upload

使用第三方库的Upload组件

这里我们使用Vue+Element的项目来做演示,使用Element里的Upload组件来上传。这里我们的服务端还是使用上面的代码。客户端代码为了简单,我使用了一个单一的index.html文件。

<div id="app">
<el-upload
class="upload-demo"
action="/upload"
:on-preview="handlePreview"
:on-remove="handleRemove"
:file-list="fileList"
list-type="picture">
<el-button size="small" type="primary">点击上传</el-button>
<div slot="tip" class="el-upload__tip">请上传你的文件</div>
</el-upload>
</div>

上面的代码参考Element文档的写法来写就可以,里面需要注意的是action和我们写原生input标签时用的action是一样的。其他代码都是Element自己的组件封装方法,这里就不再赘述。

完整代码参考 demo_upload_elment_ui

本期,关于上传组件的事就讲到这里。