微信内H5页面唤醒App

news2024/11/25 7:16:02

首先,简述一下这个需求的背景,产品希望能够让用户在微信内,打开一个h5页面,然后就能唤醒公司中维护的app,这个是为了能够更好的引流。

唤醒app的三种方案

IOS系统-Universal Link(通用链接)

Universal Links可以通过配置指定域名路径直接唤醒APP,一步到位

具体配置看这篇文章

https://juejin.cn/post/6937614343840202766

遇到的问题:

apple-app-site-association文件放在app域名(假设: https://my.app.com/)下

{
    "applinks": {
        "apps": [],
        "details": [
            {
                "appID": "******",
                "paths": [ "/abc/*" ]
            },
        ]
    }
}

使用Universal Link其实就是跳转到一个页面(中间页),地址:https://my.app.com/abc/index.html

根据上面配置,这个地址是已经固定了的,这需要跟app域名保持一致,并且在paths配置里面的目录下,为了能够获取到apple-app-site-association文件

const universalLink = 'https://my.app.com/abc/index.html?redirectUrl=' + window.location.href
location.replace(universalLink);

如果未下载app,则会跳转失败,在中间页中处理,跳转失败后再返回到当前页面。

<script>
    function getQueryStringArgs(url, opt) {
      const { decode = true, multiple = false } = opt || {};
      const args = {};
      if (!(typeof url === 'string' && url.includes('?'))) return args;

      const arr = url.split('?');
      const qs = arr.length === 2 ? arr[1] : '';
      if (!(typeof qs === 'string' && qs.length)) return args;

      const items = qs.split('&');
      for (let i = 0; i < items.length; i++) {
        const meta = items[i];
        if (!(typeof meta === 'string' && meta.includes('='))) continue;
        const item = meta.split('=');
        const key = decode ? decodeURIComponent(item[0]) : item[0];
        const value = decode ? decodeURIComponent(item[1]) : item[1];
        if (Object.prototype.hasOwnProperty.call(args, key) && multiple) {
          const temp = args[key];
          args[key] = Array.isArray(temp) ? [...temp, value] : [temp, value];
        } else {
          args[key] = value;
        }
      }
      return args;
    }
    const { redirectUrl } = getQueryStringArgs(location.href)
    if (typeof redirectUrl === 'string' && redirectUrl) {
      location.replace(redirectUrl + '?callType=universalLink') // 处理唤醒app失败场景
    }
  </script>

上面这段逻辑如果直接放在html中,最好先手动转一下ES5语法,然后压缩一下,这样兼容性好,上面这样展示,是为了可读性好。

总结:

ios系统使用Universal Link在微信和浏览器内都能够正常的唤醒App,且兼容性比较好。但是需要注意中间页域名需要跟app域名保持一致;唤醒app的h5链接域名不能跟中间页域名一致。

直接扫二维码进入另一个页面,需要进行点击操作才能跳转,IOS不允许打开页面立刻就跳转。

URL-Schemes

URL scheme是App提供给外部的可以直接操作App的规则。

  • 比如微信提供了打开扫一扫的URL scheme。weixin://dl/scan
  • 比如支付宝提供了转账的URL scheme。alipayqr://platformapi/startapp?saId=20000116
  • 比如知乎提供了打开回答页面的URL scheme。zhihu://answers/{id}

如何找到某个app的URL Scheme呢?可以看下面这篇文章

https://zhuanlan.zhihu.com/p/53439246

安卓唤醒app呢,就是使用这种方式

比如:安卓开发提供的是

那跳转的链接是什么样的呢?

const schemeURL = 'myapp://www.myapp.apk'
window.href = schemeURL;

如何判断唤醒失败呢?

没有什么好办法来判断,后面只能触发了唤醒操作之后,监听页面几秒之后是否隐藏来判断,目前默认是2秒

export function getSupportedProperty() {
  let hidden;
  let visibilityChange;

  if (typeof document.hidden !== 'undefined') {
    // Opera 12.10 and Firefox 18 and later support
    hidden = 'hidden';
    visibilityChange = 'visibilitychange';
    // @ts-ignore
  } else if (typeof document.msHidden !== 'undefined') {
    hidden = 'msHidden';
    visibilityChange = 'msvisibilitychange';
    // @ts-ignore
  } else if (typeof document.webkitHidden !== 'undefined') {
    hidden = 'webkitHidden';
    visibilityChange = 'webkitvisibilitychange';
  }

  return {
    hidden,
    visibilityChange,
  };
}
/**
 * 判断页面是否隐藏(进入后台)
 */
export function isPageHidden() {
  const ob = getSupportedProperty();
  const hidden = ob?.hidden;
  if (typeof hidden === 'undefined') return false;
  // @ts-ignore
  return document[hidden];
}
/**
 * 检测是否唤端成功
 * 在唤起执行后,当前页面调用此方法根据页面隐藏变化检测是否唤醒成功
 * @param {number} timeout 定时时间,默认2秒
 * @return {Object} Promise对象
 */
export function checkOpen(timeout = 2000) {
  return new Promise((resolve, reject) => {
    const ob = getSupportedProperty();
    const visibilityChange = ob?.visibilityChange;

    const check = () => {
      const pageHidden = isPageHidden();
      if (pageHidden) {
        resolve(); // 页面被隐藏,说明唤醒成功
      } else {
        reject(new Error('唤醒超时'));
      }
    };
    const timer = setTimeout(() => {
      check();
    }, timeout);

    const fn = () => {
      if (typeof visibilityChange !== 'undefined') {
        document.removeEventListener(visibilityChange, fn);
      } else {
        window.removeEventListener('pagehide', fn);
      }
      check(); // 唤醒执行后,立马触发页面隐藏变化,可检测是否唤醒成功
      clearTimeout(timer); // 未到达指定时间,页面隐藏变化,清除定时器
    };

    if (typeof visibilityChange !== 'undefined') {
      document.addEventListener(visibilityChange, fn);
    } else {
      window.addEventListener('pagehide', fn);
    }
  });
}

总结:

安卓使用URL Schemes在微信中是不能跳转的,在浏览器中是能够正常拉起。

微信开放标签

由于在微信环境内,所以可以使用微信提供的能力来唤醒app,微信内禁止使用URL Schemes唤醒app,其实就是微信的一种保护机制。

微信文档:

https://developers.weixin.qq.com/doc/oplatform/Mobile_App/WeChat_H5_Launch_APP.html

如上图,使用这个功能,有很多限制,而且需要配置,但是为了安卓用户成功引流,产品还是要求使用这个功能。

微信配置

1.关联App-微信开发平台

微信开发平台配置关联App,关联App需要appId,已经有App的域名

微信开发平台地址: https://open.weixin.qq.com/

2.H5页面域名配置-微信公众平台

JS安全域名需要配置当前h5页面的域名

微信公众号地址: https://mp.weixin.qq.com/

3.初始化微信SDK,需要获取签名

微信开发SDK文档

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

这需要后端开发接口, 去获取签名

使用微信开放标签说明:

https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_Open_Tag.html

async getWxSignatureData() {
      const url = window.location.href.split('#')[0];
      const res = await getJsapiSignParamers(url);
      const { appId, signature, timestamp, nonceStr } = res.data;
      wx.config({
        debug: false,
        appId: appId,
        timestamp: timestamp,
        nonceStr: nonceStr,
        signature: signature,
        jsApiList: ['showOptionMenu'], // 必填,故使用一个非实际使用的api用于填充
        openTagList: ['wx-open-launch-app'], // 可选,需要使用的开放标签列表
      });

      wx.ready(() => {
        console.info('wx sdk ready');
        console.info('调用接口初始化wx sdk 成功');
        this.initWxSDKStatus = 'success';
      });

      wx.error(res => {
        console.error('调用接口初始化wx sdk 失败', res);
        this.initWxSDKStatus = 'fail';
      });
    },

接口返回的就是这样的数据结构

只有这样才能正常初始化微信的SDK,只有正常初始化SDK才能够使用微信开放标签的能力。

然后后端开发的时候要注意:签名需要后端配置白名单ip,文档说明如下:

https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html

安卓手机,如果出现唤醒app之后,打开了应用,但是并未成功唤起,那是因为Android应用有要求,需要安卓开发兼容一下就行了~

微信环境内场景

接下来就分析一下,在微信中有几种分享的场景:

1.微信好友之间链接分享

这种方式,使用微信标签是不能唤醒App的,除非是在关注公众号里面,这个公众号就是上面绑定了JS安全域名的公众号

这样点击这个链接就能正常用微信标签唤醒

2.微信好友之间卡片分享

这种点击打开是能够正常唤醒App的,而且不需要使用公众号,但是这种分享有限制,需要打开页面点击右上角分享给其他好友会带上卡片形式,如果在浏览器中就只是复制链接了,微信不会自动识别成卡片

而且这个分享其实就是微信的一个功能

https://developers.weixin.qq.com/minigame/dev/api/share/wx.onShareAppMessage.html

3.长按识别二维码识别H5链接

这种也能正常唤醒App,而且不需要关注公众号,也很方便,不需要将链接分享给其他人,只需要将唤醒App的链接做出二维码就行了。

全部流程图

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1173811.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

invoke方法传参String数组问题——wrong number of arguments

invoke方法传参String数组问题——wrong number of arguments 问题描述一、案例准备二、错误反射调用实例三、正确反射调用实例 问题描述 今天笔者在使用invoke方法的时候&#xff0c;发现报了一个这样一个错&#xff1a;“wrong number of arguments”&#xff0c;在网上冲浪…

【Python】-- python的基本图像处理(图像显示、保存、颜色变换、缩放与旋转等)

目录 一、图像文件的读写 操作步骤&#xff1a; 显示图像文件的三个常用属性&#xff1a; 例&#xff1a; 二、图像文件的处理 常用的图像处理方法 1、图像的显示 2、图像的保存 3、图像的拷贝与粘贴 4、图像的缩放与旋转 5、图像的颜色变换 6、图像的过滤与增强 7、序…

【MySQL】用户管理权限控制

文章目录 前言一. 用户管理1. 创建用户2. 删除用户3. 修改用户密码 二. 权限控制1. 用户授权2. 查看权限3. 回收权限 结束语 前言 MySQL的数据其实也以文件形式保存&#xff0c;而登录信息同样保存在文件中 MySQL的数据在Linux下默认路径是/var/lib/mysql 登录MySQL同样也可以…

全网超细,Pytest自动化测试框架入门到精通-实战整理,一篇打通...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、Pytest和Unitt…

交叉编译程序:以 freetype 为例

1 程序运行的一些基础知识 1.1 编译程序时去哪找头文件&#xff1f; 系统目录&#xff1a;就是交叉编译工具链里的某个 include 目录&#xff1b;也可以自己指定&#xff1a;编译时用 “ -I dir ” 选项指定。 1.2 链接时去哪找库文件&#xff1f; 系统目录&#…

二叉树OJ练习题(C语言版)

目录 一、相同的树 二、单值二叉树 三、对称二叉树 四、树的遍历 前序遍历 中序遍历 后序遍历 五、另一颗树的子树 六、二叉树的遍历 七、翻转二叉树 八、平衡二叉树 一、相同的树 链接&#xff1a;100. 相同的树 - 力扣&#xff08;LeetCode&#xff09; bool isSameTree(…

前端框架Vue学习 ——(一)快速入门

文章目录 Vue 介绍Vue快速入门 Vue 介绍 Vue 是一套前端框架&#xff0c;免除原生 JavaScript 中的 DOM 操作&#xff0c;简化书写。基于 MVVM (Model-View-ViewModel)思想&#xff0c;实现数据的双向绑定&#xff0c;将编程的关注点放在数据上。官网: https://v2.cn.vuejs.or…

Flow-based models(NICE);流模型+NICE+代码实现

参考&#xff1a; 李宏毅春季机器学习NICE: Non-linear Independent Components Estimationhttps://github.com/gmum/nice_pytorch 文章目录 大致思想数学预备知识Jacobian矩阵行列式以及其几何意义Change of Variable Theorem Flow-based modelNICE理论代码 大致思想 Flow-B…

【Linux系统化学习】开发工具——gdb(调试器)

个人主页点击直达&#xff1a;小白不是程序媛 Linux专栏&#xff1a;Linux系统化学习 个人仓库&#xff1a;Gitee 目录 前言&#xff1a; gdb版本检查和安装 Debug和Release gdb的使用 其他指令 前言&#xff1a; 前几篇文章分别介绍了在Linux下的代码编辑器、编译器。…

c面向对象编码风格(上)

面向对象和面向过程的基本概念 面向对象和面向过程是两种不同的编程范式&#xff0c;它们在软件开发中用于组织和设计代码的方式。 面向过程编程&#xff08;Procedural Programming&#xff09;是一种以过程&#xff08;函数、方法&#xff09;为核心的编程方式。在面向过程…

2021年电工杯数学建模B题光伏建筑一体化板块指数发展趋势分析及预测求解全过程论文及程序

2021年电工杯数学建模 B题 光伏建筑一体化板块指数发展趋势分析及预测 原题再现&#xff1a; 国家《第十四个五年规划和 2035 年远景目标纲要》中提出&#xff0c;将 2030 年实现“碳达峰”与 2060 年实现“碳中和”作为我国应对全球气候变暖的一个重要远景目标。光伏建筑一体…

七月论文审稿GPT第二版:从Meta Nougat、GPT4审稿到LongLora版LLaMA、Mistral

前言 如此前这篇文章《学术论文GPT的源码解读与微调&#xff1a;从chatpaper、gpt_academic到七月论文审稿GPT》中的第三部分所述&#xff0c;对于论文的摘要/总结、对话、翻译、语法检查而言&#xff0c;市面上的学术论文GPT的效果虽暂未有多好&#xff0c;可至少还过得去&am…

1.Netty概述

原生NIO存在的问题(Netty要解决的问题) 虽然JAVA NIO 和 JAVA AIO框架提供了多路复用IO/异步IO的支持&#xff0c;但是并没有提供给上层“信息格式”的良好封装。JAVA NIO 的 API 使用麻烦,需要熟练掌握 ByteBuffer、Channel、Selector等 , 所以用这些API实现一款真正的网络应…

题解:轮转数组及复杂度分析

文章目录 &#x1f349;前言&#x1f349;题目&#x1f34c;解法一&#x1f34c;解法二&#xff1a;以空间换时间&#x1f95d;补充&#xff1a;memmove &#x1f34c;解法三&#xff08;选看&#xff09; &#x1f349;前言 本文侧重对于复杂度的分析&#xff0c;题解为辅。 …

02-React组件与模块

组件与模块 前期准备 安装React官方浏览器调试工具&#xff0c;浏览器扩展搜索即可 比如红色的React就是本地开发模式 开启一个用React写的网站&#xff0c;比如美团 此时开发状态就变成了蓝色 组件也能解析出来 何为组件&模块 模块&#xff0c;简单来说就是JS代…

亚马逊云科技大语言模型下的六大创新应用功能

目录 前言 亚马逊云科技的AI创新应用 ​编辑 Amazon CodeWhisperer Amazon CodeWhisperer产品的优势 更快地完成更多工作 自信地进行编码 增强代码安全性 使用收藏夹工具 自定义 CodeWhisperer 以获得更好的建议 如何使用Amazon CodeWhisperer 步骤 1 步骤 2 具体…

php7.4.32如何快速正确的开启OpenSSL扩展库,最简单的办法在这里!

&#x1f680; 个人主页 极客小俊 ✍&#x1f3fb; 作者简介&#xff1a;web开发者、设计师、技术分享博主 &#x1f40b; 希望大家多多支持一下, 我们一起进步&#xff01;&#x1f604; &#x1f3c5; 如果文章对你有帮助的话&#xff0c;欢迎评论 &#x1f4ac;点赞&#x1…

GNU ld链接器 lang_process()(二)

一、ldemul_create_output_section_statements() 位于lang_process()中11行 。 该函数用于创建与目标有关的输出段的语句。这些语句将用于描述输出段的属性和分配。 void ldemul_create_output_section_statements (void) {if (ld_emulation->create_output_section_sta…

PS Raw中文增效工具Camera Raw 16

Camera Raw 16 for mac&#xff08;PS Raw增效工具&#xff09;的功能特色包括强大的图像调整工具。例如&#xff0c;它提供白平衡、曝光、对比度、饱和度等调整选项&#xff0c;帮助用户优化图像的色彩和细节。此外&#xff0c;Camera Raw 16的界面简洁易用&#xff0c;用户可…

每日一题 187. 重复的DNA序列(中等)

由于今天做了周赛&#xff0c;每日一题就简单点直接暴力哈希 class Solution:def findRepeatedDnaSequences(self, s: str) -> List[str]:d defaultdict(int)ans []for i in range(len(s) - 9):t s[i: i 10]d[t] 1if d[t] 2:ans.append(t)return ans