微信公众号开发踩坑记录

发布于 2020-09-09  398 次阅读


在微信浏览器里可以通过jssdk调用微信的各种功能,比如微信扫一扫,获取用户列表,分享到朋友圈之类 。

但是每次调用jssdk的时候浏览器的JS必须先用wx.config完成配置和签名校验,这就需要从后端获取一组签名数据包。微信公众平台提供了这方面的文档和参考,有后端也有前端。

后端范例下载:

http://demo.open.weixin.qq.com/jssdk/sample.zip

JSSDK文档:

https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html

我使用的是php,这里需要把jssdk.php jsapi_ticket.php access_token.php三个文件都下载下来才能使用,后2个文件是用来缓存jsapi_ticket和access_token的。这两个用来给后端生成签名数据包,然后浏览器端获取签名数据包之后,用js调用jssdk传入签名数据包进行配置,通过验证之后就可以正常调用微信(微信内置浏览器)提供的功能了,这些功能都通过wx这个对象调用。这两个口令的有效期都是2小时,并且请求频率有限制,所以这个缓存机制不能省略。

jssdk.php并不是复制过来就能用的,我做了几个修改才最终适配到了我这边的需求和环境。一个是access_token.php和jsap_ticket.php的路径,由于用了MVC结构,所以改了一下jssdk.php内对这两个文件的访问,使用了完整URL路径才能正确读写。然后是请求access_token的时候一开始得到的是null,之后下载了

http://curl.haxx.se/ca/cacert.pem

这个文件,放到文件系统,更改了php配置文件:

[curl]

; A default value for the CURLOPT_CAINFO option. This is required to be an

; absolute path.

curl.cainfo="d:\xxx\xxx\cacert.pem"

然后重启php,之后就可以获取到access_token和jsapi_ticket了。当然,我开启了ssl。

还有一个坑是签名验证算法的url参数,首先我用的是frp转发,frp服务端用了ssl,但是我自己的机器没有用,通过nginx转发到本机所以没必要用ssl。因此我这边检测出来的通信协议是http而不是https,这里可能需要手动指定一下。在jssdk.php的这里:

// 注意 URL 一定要动态获取,不能 hardcode.
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
//$protocol = "https://";
$url = "$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";

如果没有使用ajax获取签名包,这里可能需要直接指定成https://

另外这个url参数必须和执行wx.config这个js代码的所在页面路径一致,因此如果你用ajax访问另外一个服务端url获取签名包,应该把执行js的页面的window.location进行url编码,跟着ajax Post参数发送到后端,后端用收到的参数解码后替代这里的url,大概改了以后是这样:

.({
    : ApiUrl + : {: purl}: : : (resp) {
        (resp.=== ) {
            sdkData = resp.conf = {
                : : sdkData.: sdkData.: sdkData.: sdkData.: []
            }console.(conf)wx.(conf)}{
            console.()}
    }: () {
        ()}
})

public function js_sdk_dataOp()
{
   $jssdk = new JSSDK("wxb412d33b4529de2d", "d8ba76212ce32f00ec97d72870ffec2e");
   $signPackage = $jssdk->GetSignPackage($_POST['purl']);
   output_data($signPackage);
}

public function getSignPackage($purl='')
{
   $jsapiTicket = $this->getJsApiTicket();

   $url = null;
   if($purl){
       $url = $purl;
   }else {
       // 注意 URL 一定要动态获取,不能 hardcode.
       $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
       //$protocol = "https://";
       $url = "$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
   }
//....
}

终于可以顺利通过验证调用扫码了,这个坑磨了我将近一天,做个记录备忘,如果帮到你了或者还有疑问,欢迎留言联系我。



点击数:148


一沙一世界,一花一天堂。君掌盛无边,刹那成永恒。