如何获取微信小程序二维码并返回给前端base64编码

因为微信小程序通过接口返回出来的图片是二进制流,我们通过后端获取小程序二维码,之后返回给前端,稍微有点小麻烦。

网上搜到大多数的解决方案不管是返回给前端 base64 编码,还是返回 url,都是通过接受微信返回的二进制流存储一张图片到服务器。笔者考虑存储服务器并不妥,本文的解决方案在不做服务器存储操作的前提下返回 base64 编码给前端。本文使用的PHP扩展包是 Guzzlehttp, 使用该扩展包,我们不必去自行封装 CURL 请求。关于该扩展包具体介绍这里不做展开,可以自行探索。

完整代码如下:

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
public function getwxacodeGetUnlimited($params)
{
$access_token = $this->generateAccessToken();
$args = [
'scene' => $params['scene']
];

if (isset($params['page']) && !empty($params['page']))
$args['page'] = $params['page'];

try {
$response = client::post($this->getUrl( 'wxacode_getUnlimited' ).'access_token='.$access_token, [ 'json' => $args ] );
if (is_null($res = json_decode($response, true))) {
$contents = 'data:'.$response->getHeader('Content-Type')[0].';base64,' .base64_encode((string)$response->getBody());
return $contents;
} else {
if (isset($response['errcode']) && $response['errcode'] != 0)
throw new LogicException('请求生成小程序码错误');
}

} catch (ClientException $e) {
$msg = $e->getResponse()->getBody()->getContents();
$msg = json_decode( $msg, 1 );
throw new \LogicException( "error :" . $msg['errcode'] . "msg :" . $msg['errmsg'] );
}
}

下面对上述代码进行解释

  • access_token 是要以 query string 的形式附加在请求地址后面的,如果添加到 POST 请求中,微信回报错的。
  • 代码中的 client 实际就是 Guzzlehttp 的实例对象。需注意 Guzzlehttp 实际的使用方式是实例对象之后以 $client->post() 这种方式调用的,笔者公司的框架对 Guzzlehttp 进行了二次封装。
  • 我们使用了 Guzzlehttppost 方法getUrl() 是我们封装的获取微信请求地址的方法,请读者自行实现,看过微信文档的话,这里不难理解,也不难实现。
  • 注意 Guzzlehttppost() 方法的第二个参数,由于微信接收的是 json 数据,所以我们采用 [ 'json' => $args ]Guzzlehttp内部已经帮我们实现了请求头的添加和数据的 json 编码。
  • 注意微信返回的数据,官方文档写的是 Buffer, 我们在接收的时候,判断只要不是 json 格式,即获取到 header 并且获取到数据流,将数据流做 base64_encode,然后拼接在data:image/jpeg;base64, 后面即构成了图片的完整 base64 编码。 其中 image/jpeg 是我们从 header 中拿到的。

    通过该种方式,我们即不需要在服务器上存储任何图片信息,以造成负担。当然如果有特殊需求的另当别论。

Author: rexmolo
Link: http://rexmolo.github.io/2020/04/03/how-to-make-wx-miniapp-acode-send-frontend/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.