The introduction
In the development of small programs after the time, meets the requirements, the need to accept small program customer service information users reply specific fingers, returns the corresponding pictures, pictures is, however, exist the oss or is in the form of specific links into base64, in the use of WeChat provide temporary material upload interface, often return to the media file parsing errors After a method to find the, Found that the basic solution is PHP, after a round of summary of various online gods solution, finally can get the desired results
Analysis of the
Temporary material interface Document address temporary material interface · applets
From the document analysis, there are several points to note when uploading temporary images:
- The media field in the image upload request is the media file identifier in form-data and contains information such as filename, Filelength, and Content-Type
- Request cannot use AXIos, axios server does not seem to support form type submission, without adding third party library, use request form method, upload
- For oss and online images, you can directly get the stream of the image through AXIos and drop it into the media
- For special base64 images, first convert Base64 into buffer, and then use Request. form to throw buffer into media
- For local images, you can use FS to create a readable stream for transmission
After analyzing the submitted stream and buffer, it is found that the images returned by network request are generally represented by filename, while base64 images are not available, so contentType and filename need to be added during transmission, otherwise wechat will fail to recognize them. See the submitted code below for details
Specific code
Obtain the corresponding format according to different types
OSS, online type pictures – get stream directly
Reading the AXIos documentation, you can see that Axios provides the ability to get a file stream directly
// Stream const {data: imgStram} = await axios.get(imgUrl, {responseType: 'Stream ',});Copy the code
Base64 images – converted to buffers
For the Base64 format, you need to remove the base identifier, otherwise the image will not display correctly
You need to fill in contentType and filename during transmission, otherwise wechat will fail to identify
ImgBuffer = Buffer(base64code. replace(/^data:image\/ w+; Base64,/, "), // remove the base identifier 'base64',);Copy the code
For local files – create a readable stream directly
const imgStram = fs.createReadStream(src))
Copy the code
2. Simply encapsulate the Request
Write the basic reference from the web, oneself wrapped a promise layer outside, convenient to use async/await
Without the addition of hack wechat server will identify the failure
Filename can write a dead one. After testing, wechat will return a different media_ID each time, so there is no need to worry about the problem caused by name duplication
function _promiseRequest({ imgStram = null, imgBuffer = null, accessToken }) { const url = `https://api.weixin.qq.com/cgi-bin/media/upload?access_token=${accessToken}&type=image`; return new Promise((resolve, reject) => { const req = request.post( { url, headers: { accept: '*/*', }, }, (err, res) => { if (err) { reject(err); } try { const resData = JSON.parse(res.body); // media_id resolve(resData); } catch (e) { console.log(e) } }, ); const form = req.form(); ImgBuffer {form.append('media', imgBuffer, {contentType: 'image/jpeg', // 'code.jpg', // wechat recognition needs}); } else if (imgStram) { form.append('media', imgStram); } form.append('hack', ''); }); }Copy the code
The last
Github-substack/Stream-handbook: How to Write Node Programs with Streams