1. 前言:
picgo插件的简单开发
上篇文章我们简单写了picgo上传插件,但是当我们测试的时候,发现问题了,后端MultipartFile file
接受到的文件为null。
2. 排查问题:
参考的文档
- picgo api列表
- 关于multipart form-data中filename的问题
2.1. 我们先排查前端
const handle = async (ctx) => {let userConfig = ctx.getConfig('picBed.haowan-uploader')if (!userConfig) {throw new Error('Can\'t find uploader config')}const Url = userConfig.Urlconst Token = userConfig.Tokenconst imgList = ctx.outputfor (let i in imgList) {let image = imgList[i].bufferif (!image && imgList[i].base64Image) {image = Buffer.from(imgList[i].base64Image, 'base64')}const postConfig = postOptions(Url, Token, imgList[i].fileName, image)let body = await ctx.request(postConfig)body = JSON.parse(body)return ctx
}const postOptions = (Url, Token, fileName, image) => {return {method: 'POST',url: Url + `/api/picgo/upload`,headers: {"contentType": 'multipart/form-data','Authorization': Token,'User-Agent': 'PicGo'},formData: {file : image,fileName}}
}
- 我首先考虑的是我api使用问题
🌴我使用的是pico的.request
方法,作者描述是通过使用axios实现的。
🌴使用formdata属性配置表单数据是没有问题的,可以看到picgo的底层通过读取formdata属性,把你所配置的数据读取配置到axios发送的data数据中。是axios的常用实现。
😄 由于我们使用的是picgo gui,所以控制台无法方便的使用,所以我们下面从后端排查数据是否发送
2.2. 排查后端
-
在参数接收这里点上debug
🌴我们可以看出并非没有接受文件,只是在最后并没有转换成文件。
-
查看body流读取的源码
Collection<Part> parts = request.getParts();this.multipartParameterNames = new LinkedHashSet(parts.size());MultiValueMap<String, MultipartFile> files = new LinkedMultiValueMap(parts.size());Iterator var4 = parts.iterator();while(var4.hasNext()) {Part part = (Part)var4.next();String headerValue = part.getHeader("Content-Disposition");ContentDisposition disposition = ContentDisposition.parse(headerValue);String filename = disposition.getFilename();if (filename != null) {if (filename.startsWith("=?") && filename.endsWith("?=")) {filename = StandardMultipartHttpServletRequest.MimeDelegate.decode(filename);}files.add(part.getName(), new StandardMultipartFile(part, filename));} else {this.multipartParameterNames.add(part.getName());}}this.setMultipartFiles(files);
String filename = disposition.getFilename();
,由于这里文件名为空,以致于mvc根本不处理文件流。
那么解决方案就显而易见,给添加上文件流就行。
3. 解决方案(添加文件名):
- https://www.rfc-editor.org/rfc/rfc1867 (formdata上传文件描述)
2. formdata buffer流添加文件名
formData: {file: {value: image,options: {filename: fileName}}
可以在formdata中可选属性options添加文件名的选项。就可以成功读取了。