uploader + node 进行文件上传服务
技术栈
文档类上传(.xlsx .xls .docx .doc .pdf)
前端的处理
<a-upload
accept=".xlsx .xls .docx .doc .pdf"
:file-list="fileList"
:before-upload="beforeUpload"
:custom-request="customRequest"
@change="onChange"
>上传</a-upload>
methods: {
data() {
return {
fileList: [] as any,
};
},
methods: {
beforeUpload(file) {
console.log('file:', file);
if (file.name.length > 128) return false;
},
onChange({ file, fileList }) {
console.log(file.status);
fileList = fileList.slice(-1);
fileList = fileList.map(file => {
if (file.response) file.url = file.response.url;
return file;
});
this.fileList = fileList.filter(file => !!file.status);
},
async customRequest(option) {
console.log('option', option);
try {
const formData = new FormData().append('file', option.file);
const data = await http.post('/upload', formData, {
headers: { 'Content-Type': 'multipart/form-data' }
});
option.onSuccess();
} catch(err) {
option.onError(err);
}
}
}
}
说明:
一、customRequest 中的option参数, 除携带当前文件的信息外, 还有处理三种状态的回调可供选择 二、这里用到的请求(http)是我当前项目中axios封装的请求, 实际开发中, 替换成你们自己的axios请求和对应的接口
node端的处理
router
module.exports = (app) => {
const { controller, router } = app;
const v1 = router.namespace('/v1');
v1.resources('uploader', '/upload', controller.upload);
}
controller
const { Controller } = require('egg');
class Uploader extends Controller {
async create() {
const { ctx, service } = this;
const file = ctx.request.files[0];
const index = file.filename.lastIndexOf('.');
const fileType = file.filename.slice(index + 1);
const data = await service.appTest.upload(file, fileType);
ctx.body = data;
}
}
module.exports = Uploader;
service
const { Service } = require('egg');
const FormData = require('form-data');
const fs = require('fs');
class Uploader extends Service {
async upload(file, fileType) {
const formData = new FormData();
const { filename } = file;
const readStream = fs.createReadStream(file.filepath);
formData.append('file', readStream, { filename });
formData.append('file_type', fileType);
formData.append('file_name', file.filename);
const length = await new Promise((resolve) => {
formData.getLength((err, length) => {
if (err) return;
resolve(length);
});
});
const formHeaders = formData.getHeaders();
formHeaders['Content-Length'] = length;
const data = await this.ctx.axios.post(
`/java/upload`,
formData,
{ headers: formHeaders }
);
return data;
}
}
module.exports = Uploader;
说明:
一、这里使用了egg-router-plus插件, 是为了解决路由过多的问题, 可以单独给每个模块开辟一个命名空间, 感兴趣可以点击查看 二、为了方便 这里使用了RESTful 的方式来定义路由 三、controller中获取的web传过来的file信息:
四、读取成readStream后, 最终传给后端的formaData
图片类上传(.png .jpg)
注意: 这里其实想介绍下图片预览 的功能preview (其他在文档类上传中重复过的步骤, 这里就不再赘述了)
前端的处理
<a-upload-dragger
name="image"
accept=".img,.png"
list-type="picture-card"
:show-upload-list="{showRemoveIcon:false,showPreviewIcon:true}"
@preview="onPreview"
:file-list="fileList"
:before-upload="beforeUpload"
:custom-request="customRequest"
@change="onChange"
></a-upload-dragger>
<a-modal :visible="previewVisible" :footer="null">
<img :src="previewImage" />
</a-modal>
data() {
return {
previewImage: '',
previewVisible: false,
};
},
methods: {
getBase64(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
reader.onerror = error => reject(error);
});
},
async handlePreview(file) {
console.log(file);
if (!file.url && !file.preview) {
file.preview = await this.getBase64(file.originFileObj);
}
this.previewImage = file.url || file.preview;
this.previewVisible = true;
},
async customRequest(option) {
}
}
说明
一、预览函数 onPreview 获取到的参数信息: 二、上传图片预览效果:
另: upload组件部分属性(详情见官网)
API | 说明 | 类型 | 默认值 |
---|
accept | 接受上传的文件类型 | string | 无 | customRequest | 自定义上传方法 | Function | 无 | fileList | 已经上传的文件列表(受控) | object[ ] | 无 | name | 发到后台的文件参数名 | string | ‘file’ | listType | 上传列表的内建样式,支持三种基本样式 text, picture 和 picture-card | string | ‘text’ | showUploadList | 上是否展示 uploadList | Boolean or { showPreviewIcon?: boolean, showRemoveIcon?: boolean } | true | remove | 点击移除文件时的回调 | Function(file): boolean | Promise | 无 |
事件 | 说明 | 回调参数 | 默认值 |
---|
change | 上传文件改变时的状态 | Function | 无 | preview | 点击文件链接或预览图标时的回调 | Function(file) | 无 | reject | 拖拽文件不符合 accept 类型时的回调 | Function(fileList) | 无 |
好啦~今天就分享到这里!
|