似乎当thinkjs升级到3.0后,才接手了一个项目。只是在实际运用过程中,还是发现了与2.2的些许差别——今天先分享关于图片上传的一些问题。
1.上传文件,我们选择了jQuery的插件:http://www.jq22.com/jquery-info230
屡试不爽,各种好评。只是后来项目上线的时候,才发现保存在数据库的img都没有后缀名……
这是什么情况。。。。。。原谅自己没仔细看数据库存的方式,只是从表面看见图片可以显示了就随意了,结果导致后来又坑了自己。检查了很久,还是从自身找问题吧,翻看thinkjs文档,有什么差距呢?
给接口的文件路径中缺少后缀名,导致接口返回过来的文件也就缺少了后缀!
那合理的解决办法呢?
1.接口修改一下方法?No,他们说这是一个公共方法,不能因为一个项目而更改接口;
2.我来修改方法,将完整的图片路径传给接口然后就ok了。
1.后台上传方法js:
1 async uploadAction() { 2 if (!think.isEmpty(this.file(‘uploadFile‘))) { 3 //进行压缩等处理 4 let file = think.extend({}, this.file(‘uploadFile‘)); 5 6 //保存文件的路径 7 let savepath =think.ROOT_PATH + ‘/www/static/uploadimg/‘; 8 let filepath = file.path; //文件路径 9 let filename = file.name; //文件名 10 let suffix = filename.substr(filename.lastIndexOf(‘.‘) + 1); //文件后缀 11 let newfilename = Math.random().toString(36).substr(2) + ‘.‘ + suffix; 12 13 //读文件 14 let datas = fs.readFileSync(filepath); 15 //写文件 16 fs.writeFileSync(savepath + newfilename, datas); 17 let newpath = savepath + newfilename; 18 let imageSizeObj=config.imageSize[this.get("tag")]; 19 let headers={"zipImage": ‘[{"mode":"‘ + imageSizeObj.zipMode + ‘","w":‘ + imageSizeObj.width + ‘,"h":‘ + imageSizeObj.height + ‘}]‘}; 20 let result = await imgutil.upload(newpath, filename, suffix, headers, this.get(‘type‘)); 21 22 if (!result.err) { 23 let resultObj = JSON.parse(result.result); 24 resultObj[‘imgSiteUrl‘] = this.config(‘imgSiteUrl‘); 25 return this.success(resultObj); 26 } else { 27 this.fail(result.result); 28 } 29 } 30 }
之前是因为获取到的file.path中缺少后缀,于是就手动将图片上传至项目指定路径,传给接口一个带有后缀的文件路径最后再删除掉改文件;
2.公共方法中:
1 /** 2 * authon:zhengyeye 3 * create:2018-02-07 4 * update:2018-03-30 5 * desc:图片上传工具类 6 */ 7 8 import request from ‘request‘; 9 import fs from ‘fs‘; 10 import config from ‘../config/config.js‘; 11 var imgUtil = (module.exports = {}); 12 /** 13 * 14 * @param filepath 文件路径 15 * @param filename 文件名称 16 * @param headers 请求头 17 * @param filetype 文件类型 18 * @param suffix 文件后缀 19 * @returns {Promise.<*>} 20 */ 21 22 imgUtil.upload = async function(filepath, filename,suffix,headers,filetype) { 23 let reqUrl = config.postImgUrl; 24 if (‘image‘ == filetype && !(suffix == "jpg" || suffix == "png" || suffix == "jpeg" || suffix == "bmp")) { 25 //删掉上传的文件 26 fs.unlinkSync(filepath); 27 return {err:true,result:"上传图片格式有误,请重新上传!"}; 28 } 29 let req = think.promisify(request.post); 30 31 let options = { 32 url: reqUrl + filetype + ‘/‘, 33 method: ‘post‘, 34 headers: headers, 35 formData: { 36 file: fs.createReadStream(filepath) 37 } 38 }; 39 let res = await req(options); 40 let result = res.body; 41 //删掉上传的文件 42 fs.unlinkSync(filepath); 43 if (result) { 44 return { err: false, result: result }; 45 } else { 46 return { err: true, result: ‘上传失败,请稍后再试!‘ }; 47 } 48 };
3.配置文件中也有修改:
1 ... 2 3 imageSize: { 4 users: { width: 300, height: 300, zipMode: ‘Fit‘ }, //账号头像 5 advImg: { width: 800, height: 370, zipMode: ‘Fit‘ } //广告图片 6 } 7 8 ...
(配置文件中的只是为了配合接口端对图片进行裁剪);
4.这样处理过后,是可以返回正确的图片路径了,但是却存在另一个问题:
然后,这个问题就导致自己做完加班到晚上九点多,还满眼是泪……(毫无成就感,也不知道你能感同身受不?再加上叶叶有点小“洁癖”、小“固执”,马上结束的项目突然出现一个问题,那种感觉真心不好)
接着呢?就谷歌、百度出各种:
1.https://github.com/thinkjs/thinkjs/issues/1105
2.https://github.com/thinkjs/think-payload#options
3.https://github.com/thinkjs/thinkjs/issues/899
参考了大家的经验,再结合我的实际情况呢,于是就完美的解决了问题:
1.package.json中没有think-payload模块,npm 一下;
2.middleware.js中我却没有修改任何东西。
可以美美的过个周末啦……