最近做项目的时候遇到了一个小细节问题,对接第三方云平台接口拿到了一个图片的 base64 编码,微信小程序中需要使用这个图片,并且将图片上传至java后端服务器上。 后端提供了图片上传接口,但只支持 FormData
文件流,不支持 base64 直接传,前端需要考虑的就是如何把 base64 编码变成图片。
这个其实 web 端已经有成熟的方案了,将 base64 转换成二进制图片 Blob
,再组装 FormData 对象即可完成。
贴一段示例代码,应该很容易看懂:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 var base64String = '/*base64图片串*/' ;var bytes = window .atob (base64String.split (',' )[1 ]);var ab = new ArrayBuffer (bytes.length );var ia = new Uint8Array (ab);for (var i = 0 ; i < bytes.length ; i++) { ia[i] = bytes.charCodeAt (i); } var blob = new Blob ([ab], {type : 'image/jpeg' }); var fd = new FormData ();fd.append ('file' , blob, Date .now () + '.jpg' );
然而这一切到了微信小程序 上,开始变得困难了 =。=
微信小程序里没有 atob
,也不支持 Blob
对象,这种转换不允许放在微信小程序上前端执行。这时候我只好退而求其次,让 nodejs 作为中间件去完成这个小任务。
nodejs我用的就是最基础的 express
, 实现方法也很简单,但是网上关于这块的介绍比较少,所以我在这记录分享一下。
首先,node 环境中没有 FormData
对象,需要引入这个模块。
其次,node 环境中需要一个发起 http 请求的模块,我在 browser 端比较惯用 axios
,所以这里也用了 axios
然后可以开始写转换代码了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 const axios = require ('axios' );const FormData = require ('form-data' );function uploadBase64File (base64, url, contentType = 'image/jpeg' ) { const formData = new FormData (); const filename = 'tempfile.' + contentType.split ('/' )[1 ]; const fileContent = Buffer .from (base64, 'base64' ); formData.append ('image' , fileContent, { filename, contentType, knownLength : fileContent.byteLength , }); const formHeaders = formData.getHeaders (); return new Promise ((resolve, reject ) => { axios ({ url, method : 'post' , data : formData, headers : { ...formHeaders, }, }) .then (res => { resolve (res.data ); }) .catch (err => { reject (err); }); }); }
里面用到的 Buffer
是 node 中自带的二进制处理模块,formData 只要把文件信息补全,上传流程就没问题了。