这几天工作中遇到需要预生成微信二维码的需求。
小程序开发文档中讲的也非常简略,B接口很坑爹地返回一个二进制流(也许这就是无限制数量的原因吧,微信只提供计算服务,不提供存储服务。)
原本利用fetch来处理,着实费了一番手脚
return fetch(url, init)
.then(
(response)=>{
return response.text()
})
通过这种形式获取微信api返回的二维码二进制流,再上传到七牛。是行不通的,原因是response.text()包含的并不仅仅是图片的二进制数据,使整个网页返回的数据。跟本文需求是风马牛不相及的。
花了时间查了下fetch pipe的实现,很遗憾没有查到。
幸运的是request包含了pipe的实现。git地址:https://github.com/request/request
废话不多说,直接上码。
const request = require('request');
const concat = require('concat-stream');
const qiniu = require('qiniu');
function concatPro (buffer){
var formUploader = new qiniu.form_up.FormUploader(config);
var putExtra = new qiniu.form_up.PutExtra();
/**
* 两种形式。
* 1、直接利用pipe过来的buffer,put到七牛
* 2、将pipe过来的buffer转成可读流,putStream到七牛
* 照qiniu\qiniu\storage\form源码来看,两者无区别,本身都会转成可读流形式putStream
*/
// const readableStream = Stream.Readable();
// readableStream.push(buffer);
// readableStream.push(null);
return new Promise(
(resolve, reject)=> {
// formUploader.putStream(uploadToken, fileName, readableStream, putExtra, function (respErr, respBody, respInfo) { // 传入可读流
formUploader.put(uploadToken, fileName, buffer, putExtra, function (respErr, respBody, respInfo) { // 传入buffer
if (respErr) {
reject(respErr);
}
if (respInfo.statusCode == 200) {
console.log(respBody);
} else {
console.log(respInfo.statusCode);
console.log(respBody);
}
resolve(respBody);
});
});
}
return request({
method: "post",
url: URL,
body: JSON.stringify(
{
scene: xxx,
page: xxx
}
)
// pipe导出的是数据流,而输出concatPro是个普通函数,我们需要把输入流转化为普通的buffer,这时使用concat-stream
}).pipe(concat(concatPro));
拓展阅读: 理解nodejs的stream和pipe机制