欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

微信开放标签 wx-open-launch-app 唤醒小程序踩坑记录

最编程 2024-04-26 09:23:28
...

微信今年新出的一个标签,可以通过它在微信浏览器唤醒手机app。 在调试的时候发现了无数问题,而且文档论坛都没有任何答案,自己一步步爬出坑的,在此记录一下,以便后人~

使用场景就是app分享卡片到微信端,微信端点击卡片直接在内置浏览器打开网页,用户在浏览网页的时候通过点击按钮等交互唤醒app,已达到引流到app的效果。

前景提要

想在微信中唤醒app常规的方法有universal link,但是只支持ios,所以我们使用了微信提供的开放标签wx-open-launch-app

这里也讲一下universal link的坑,universal link的使用原理就是通过在服务器配置一个json文件然后ios可以识别写入到系统,这样我们访问对应网址的时候即可唤醒app。

但在微信环境中有个问题,就是必须跨域,同域之间的universal link是不会生效的。

雷点

1.安全域名

在微信开放平台的配置中,我们会看到类似服务号的一个安全域名配置,不过他两是完全不一样的。

这里的js安全域名需要完全匹配

举个例子,如果我们设置的安全域名是163.com,那么我们只能在在这个域名下面使用,即使是子域名more.163.com/也是无法唤醒微信开放标签的,会报错launch:fail_check fail

image.png

环境

如果要唤醒app,必须使用sdk生成的卡片,或者使用微信开发者工具的浏览功能,不然会报错launch:fail

image.png

image.png只能通过上述两种方法唤醒!!!

举个例子

假设上面我们分享的卡片地址是163.com/share,当我们点击卡片打开网页的时候是能唤醒开发标签的,但如果我们把这个卡片的地址163.com/share手动输入到聊天框,然后通过点击这个链接打开app,那么就会唤醒失败报错。

这一点非常离谱,文档没有任何提示!

方案

微信的支持真的一言难尽,所以贴一下我的代码。

标签定义

如果你都跟我一样使用了ts,那么引入微信开放标签是无法识别的,会报错,所以首先需要我们定义一下。

declare namespace JSX {
  interface IntrinsicElements {
    'wx-open-launch-app': any;
  }
}

使用诀窍

另外就是wx-open-launch-app标签的使用了,文档里面有说到如果要触发唤醒事件,必须在交互的地方写上wx-open-launch-app标签,也就是说,必须通过点击wx-open-launch-app这个标签才能唤醒app。

那么假如我们很多地方都需要的话总不可能所有地方都包一层吧?

所以这里我用了一个很巧妙的办法:维持原有标签的不变,把wx-open-launch-app标签封装成一个组件,在需要的地方引入组件,并且通过绝对定位覆盖原有标签,通过层级优先级实现wx-open-launch-app标签的优先触发。

并且这里通过样式定义把微信的标签样式给隐藏掉,视觉上看起来微信标签是不存在的,保证原有代码的可读性。

代码如下

const WechatOpenApp = (props: any) => {
  const launchBtn = useRef<HTMLButtonElement>(null!);

  useEffect(() => {
    if (!IS_WECHAT) {
      return;
    }
    const ready = () => {
      console.log('wx ready');
    };
    const launch = (e: any) => {
      console.log('wx launch', e);
    };
    const error = (e: any) => {
      console.log('wx error', e);
      Toast.show({
        content: '微信唤醒服务失败,错误信息:' + e.detail.errMsg,
      });
    };
    const ref_ = launchBtn.current;
    ref_.addEventListener('ready', ready);
    ref_.addEventListener('launch', launch);
    ref_.addEventListener('error', error);
    return () => {
      ref_.removeEventListener('ready', ready);
      ref_.removeEventListener('launch', launch);
      ref_.removeEventListener('error', error);
    };
  }, []);

  const style = { position: 'absolute', top: 0, left: 0, right: 0, bottom: 0 };
  return IS_WECHAT ? (
    <wx-open-launch-app
      ref={launchBtn}
      appid={WECHAT_OPEN_APP_ID}
      extinfo={encodeURIComponent(location.pathname + location.search)}
      style={style}
    >
      <script type="text/wxtag-template">
        <button
          style={{
            opacity: 0,
            position: 'absolute',
            top: 0,
            left: 0,
            right: 0,
            bottom: 0,
          }}
        ></button>
      </script>
    </wx-open-launch-app>
  ) : null;
};

上面的代码之所以看起来有点奇怪,是因为微信标签这种写法是样式隔离的,标签里面的样式无法读取外部样式,包括类名等等,所以我们只能通过行内样式来定义。

最后如果后续有相关使用问题可以留言咨询~ 微信是真的坑~