作者:suan_suanhttps://segmentfault.com/a/1190000018661914

H5 唤醒APP功能

最近遇到一个需求,需要在从APP分享出去的H5页面中,带有一个立即打开的按钮,如果本地安装了app,那么就直接唤起本地的app,如果没有安装,则跳转到下载。

这是一个很正常的推广和导流量的策略。前端小白从来没有做过这个需求,只能开始哼唧哼唧地开启自己的度娘和谷歌之旅。

经过一段时间的探索之旅发现里面的学问很多,要做一个兼容性很好的方案,就需要考虑各种情况,在不同的情况适配不同的方案。

比方说用户是在手机浏览器打开还是微信中打开,或者是在pc中打开,universal腾讯应用宝直接打开 APP link是否被关闭等,这就使代码实现变得复杂,且容易出错,且还有安卓平台机型众多、浏览器众多等导致的兼容问题。

由于时间有限,这次主要先介绍一个比较普遍的使用URL Scheme进行App跳转的方法。

URL Scheme —— 唤端媒介

来源

一般来说,我们使用的智能设备上有许多我们的个人信息。

比如:联系方式、银行卡/信用卡信息、支付宝/Paypal/各大商城的账户密码、照片甚至行程与位置信息等。

如果说,你设备上的每一个应用,不管是官方的还是你从任何商城安装的应用都可以随意地获取这些信息,那么你轻则收到骚扰信息和邮件、重则后果不堪设想。

如何让这些信息不被其它应用随意使用,或者说,如何让这些信息仅在设备所有者本人知情并允许的情况下被使用,是所有智能设备与操作系统所要在乎的核心安全问题。

针对这个问题,苹果使用了名为「沙盒」的机制:应用只能访问它声明可能访问的资源。一切提交到 App Store 的应用都必须遵守这个机制。

在安全方面沙盒是个很好的解决办法,但是有些矫枉过正。敏感的个人信息我们不愿意透露,却不代表所有的信息我们都不想与其它应用共享。

因此,我们急需要一个辅助工具来帮助我们实现应用通信, URL Schemes 就是这个工具。

URL Schemes是什么

[scheme]://[host]/[path]?[query]

我们拿 https://www.baidu.com 来举例,scheme 自然就是 https 了,后面拼接的是传递的参数。

URL Schemes 没有特别严格的规范,所以后面参数的具体定义是app开发者去自定义。

就像给服务器资源分配一个 URL,以便我们去访问它一样,我们同样也可以给手机APP分配一个特殊格式的 URL,用来访问这个APP或者这个APP中的某个功能(来实现通信)。

APP得有一个标识,好让我们可以定位到它,它就是 URL 的 Scheme 部分。

但是,两者还有几个重要的区别:

  • 所有网页都一定有网址,不管是首页还是子页。但未必所有的应用都有自己的 URL Schemes,更不是每个应用的每个功能都有相应的 URL Schemes。几乎没有所有功能都有对应 URL 的应用。一个 App 是否支持 URL Schemes 要看那个 App 的作者是否在自己的作品里添加了 URL Schemes 相关的代码。
  • 一个网址只对应一个网页,但并非每个 URL Schemes 都只对应一款应用。这点是因为苹果没有对 URL Schemes 有不允许重复的硬性要求,所以曾经出现过有 App 使用支付宝的 URL Schemes 拦截支付帐号和密码的事件。
  • 一般网页的 URL 比较好预测,而URL Scheme 因为没有统一标准,所以非常难猜,通过猜来获取 应用的 URL Schemes 是不现实的。

前面普及了一下URL Schemes的相关知识,作为个前端开发者,就不去深究其中的原理,都交给app开发者吧。

接下来开始我们的正题。首先当然是要客户端提供App的Url Schemes。

用浏览器去打开scheme

在浏览器中打开 scheme 就像打开一个不同的http地址一样。可以在一个 a 标签中打开。

打开App

打开应用

点击上面的H5页面中的链接将会尝试唤醒对应app,在一些浏览器中,可能会弹出一个提示框,询问用户是否允许打开应用。

如果打开的 scheme 在本地没有对应的 app,则点击不会反应。

当然还可以使用 JavaScript 代码打开,只需要添加相应的事件触发和处理即可。

在JavaScript代码中打开连接有以下几种方式:

  • 新建一个隐藏的 iframe ,地址指向需要打开的url
  • 使用 window.location 或者 window.location.href 刷新当前页面
  • 新建一个隐藏的 a 标签,地址指向打开的url,并触发打开链接事件
  • 动态创建一个script脚本,在这个脚本中新建一个a标签并打开

// 打开url的方式

var urlOpen = {

// 在ios支持不好

'iframe' : function(url) {

var iframe = document.createElement('iframe');

iframe.style.display = 'none';

iframe.src = url;

document.body.appendChild(iframe);

},

'location' : function(url) {

window.location.href = url;

},

'href' : function(url) {

var a = document.createElement('a');

a.style.display = 'none';

a.href = url;

document.body.appendChild(a);

a.click();

},

'script' : function(url) {

var script = document.createElement('script');

script.setAttribute('type', 'test/javascript');

script.innerHTML = '(function(){' +

'var a = document.createElement("a");' +

'a.style.display = "none";' +

'a.href = "' + url.replace(/"/g, '"') + '";' +

'document.body.appendChild(a);' +

'a.click();' +

'})()';

document.body.appendChild(script);

},

'open' : function(url) {

window.open(url);

}

};

以上方法是只是解决了在已安装App设备唤醒App的功能,并不能判断是否已安装App,没有安装即跳转至下载链接。

浏览器判断是否安装应用

在浏览器实际上是没有能力判断手机里是否安装了某个App的,所以只能够采取一种投机取巧的方式。

在JavaScript中判断页面是否进入后台来判断打开成功。Html5提供了下列事件和属性可以利用:

  • pagehide : 页面隐藏时触发
  • visibilitychange : 页面隐藏没有在当前显示时触发(切换tab也会触发该事件)
  • document.hidden : 当页面隐藏时,该值为true,显示时为false

上面这些事件或者属性并不是所有浏览器都支持。下面是一个给出为id为openBtn 的按钮添加打开scheme或者下载事件的例子,但对于Android 4.4版本以下则不支持

var downloader,

scheme = 'luwei://', // 需要打开的app scheme 地址

iosDownload='http://xxx.com'; // 如果打开scheme失效的app下载地址

andDownload = 'http://xxx.com';

var u = navigator.userAgent;

var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Linux') > -1; //g

var isIOS = !!u.match(/(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端

// 给 id 为 openBtn 的按钮添加点击事件处理函数

document.getElementById('openBtn').onclick = function () {

window.location.href = scheme; // 尝试打开 scheme

// 设置3秒的定时下载任务,3秒之后下载app

downloader = setTimeout(function(){

if(isAndroid) {

window.location.href = andDownload;

}

if(isIOS) {

window.location.href = iosDownload;

}

}, 3000);

};

document.addEventListener('visibilitychange webkitvisibilitychange', function () {

// 如果页面隐藏,推测打开scheme成功,清除下载任务

if (document.hidden || document.webkitHidden) {

clearTimeout(downloader);

}

});

window.addEventListener('pagehide', function() {

clearTimeout(downloader);

});

没有完美的方案

  • 微信中无法唤醒App,需要“用浏览器打开”是因为微信对所有的分享链接接做了scheme屏蔽,也就是说分享连接中所有对于scheme的调用都被微信封掉了。有些app是能在微信打开是因为微信有一个白名单(有关系就是不错),对于在白名单中的分享链接是不会屏蔽掉scheme调用的。
  • 本文只是小小地抛个砖,介绍了一种比较常用简单的方法去唤醒app,该方案兼容性不是特别好吧。要做出一个比较完美的方案还需要细细去钻研,还需要不停地去搬砖~不说了,搬砖去了~

以上就是今天的知识分享啦~

如果大家有问题或者想了解更多的

技术干货可以私信发送【微信】添加朗妹儿微信哟~

h5 iframe显示不全_干货|H5 唤醒APP小记相关推荐

  1. h5 iframe显示不全_H5 唤醒APP小记

    H5 唤醒APP功能 最近遇到一个需求,需要在从APP分享出去的H5页面中,带有一个立即打开的按钮,如果本地安装了app,那么就直接唤起本地的app,如果没有安装,则跳转到下载.这是一个很正常的推广和 ...

  2. h5封装去底部_干货分享 | 一步一步教你在SpringBoot中集成微信支付H5支付

    一:开发文档场景介绍 H5支付是指商户在微信客户端外的移动端网页展示商品或服务,用户在前述页面确认使用微信支付时,商户发起本服务呼起微信客户端进行支付. 主要用于触屏版的手机浏览器请求微信支付的场景. ...

  3. gif透明背景动画_干货 | H5动画制作技巧

    近年来,H5页面火爆整个移动互联网,这些页面的炫酷展现,都离不开动画制作,而动效设计和制作早已成为一名合格设计师必须掌握的技能. 目前,设计师制作H5页面更多的是借助H5制作工具,本文将以H5制作工具 ...

  4. H5 唤醒APP小记

    最近遇到一个需求,需要在从APP分享出去的H5页面中,带有一个立即打开的按钮,如果本地安装了app,那么就直接唤起本地的app,如果没有安装,则跳转到下载.这是一个很正常的推广和导流量的策略.前端小白 ...

  5. html iframe显示不全,滚动的iframe解决,但在iframe页面显示不全

    我试图滚动iOS上的iframe,我成功了,它的滚动的好,参考:滚动的iframe解决,但在iframe页面显示不全 但是,所有的解决方案都有一个问题:iframe页面没有完全显示... 我测试了我的 ...

  6. html 横屏内容显示不全_为什么我的文本显示不全?

    在实际工作中,经常会遇到文本显示不全的情况,比如表格里的文本显示不全等情况,你一般是怎么操作呢?本期与大家分享几种常见的原因. 1.Word表格文本显示不全 如下图所示,表格里面的文本显示不全,这时该 ...

  7. 天正坐标标注显示不全_广联达导入CAD图纸不显示怎么办?

    第一步,操作之前先点击CAD左上角,点开后有一个图形实用工具,点开有一个核查,输入y,然后核查完后,在框选输入purge,回车全部清理. 情况一:图纸导入不显示或者显示不全,但是在CAD里显示正常. ...

  8. word中图片为嵌入式格式时显示不全_打印Word图片显示不全 Word2007图片显示不全解决方法...

    打印Word图片显示不全 Word2007图片显示不全解决方法,平凡的世界平凡的你,努力学习使我们变得不平凡,今天要介绍的知识是打印Word图片显示不全的相关知识,你准备好学习打印Word图片显示不全 ...

  9. word中图片为嵌入式格式时显示不全_图片在word中显示不全怎么处理_word图片显示不全怎么办-win7之家...

    我们在编辑word文档时,会需要插入一些图片来做为装饰或者用来标识,也会出现插入的图片显示不全的情况,要是遇到这种情况该怎么办,那么图片在word中显示不全要怎么处理呢,下面小编给大家分享图片在wor ...

  10. h5 iframe嵌套页面_汇总IOS下奇葩BUG以及iframe嵌套页面带来的一些困扰

    做H5开发,安卓和IOS的兼容问题经常会困扰我们,尤其是跟第三方平台合作,用到iframe嵌入式应用,令很多Web前端开发的童鞋脑壳疼,相信大家也入了不少坑,且踩且珍惜吧,呵呵^_^.今天抽时间整理一 ...

最新文章

  1. 解题报告(十八)数论题目泛做(Codeforces 难度:2000 ~ 3000 + )
  2. IOS开发笔记8-C语言基础复习
  3. 如何在7分钟内黑掉40家网站?
  4. 九、表达式求值(1)
  5. [C++][数据结构]栈(stack)的实现
  6. 一套优雅的 Go 错误问题解决方案
  7. 515Nod 1126 求递推序列的第n项【矩阵快速幂】
  8. 【转载】图片 CSS:怎样才能 “响应式 + 固定宽高比例”?
  9. 表数据都删了一半,可我的表文件咋还是那么大
  10. 瑞幸咖啡股价再大涨超36% 目前总市值约13.87亿美元
  11. 掐头法和去尾法记音标
  12. 如何学习前端开发,有哪些前端教程,前端学习路线图?
  13. codeforces 848B Rooter's Song 思维题
  14. CRC32 在 java中使用
  15. win11 恢复win10开始菜单及任务栏
  16. P2P技术体系结构与分类
  17. YOLO3实践应用之搭建开发环境(Python 3.6 、TensorFlow1.5版本)
  18. 基于JAVA疫情防控期间网上教学管理计算机毕业设计源码+系统+mysql数据库+lw文档+部署
  19. nas设备在通用服务器的基础上对文件服务,NAS网络存储设备将取代文件服务器
  20. 99%的人误解BLM中的“战略”与“执行”的关系及错误认为BLM/BEM就是战略解码的全部!

热门文章

  1. Vmware View Client登陆后无法使用键盘输入
  2. 在写spring项目的时候,有时候需要写ApplicationContext,有时候不要写ApplicationContext
  3. 如何让webpack打包的速度提升50%?
  4. 32位电脑ODBC连接
  5. 团队项目第一阶段站立会议01
  6. android 开发怎么让程序生成的图片文件不会被系统扫描到
  7. OpenCV教程(42) xml/yaml文件的读写
  8. Ekho TTS 5.1发布
  9. 带着梦想,追逐属于你我的那份真彩
  10. PHP获取表单数据的方法有几种,php获取表单数据的两种方法说明