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:

  1. 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
  2. Request cannot use AXIos, axios server does not seem to support form type submission, without adding third party library, use request form method, upload
  3. For oss and online images, you can directly get the stream of the image through AXIos and drop it into the media
  4. For special base64 images, first convert Base64 into buffer, and then use Request. form to throw buffer into media
  5. 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