html与app交互
1,h5唤醒app方式
参考: https://zhuanlan.zhihu.com/p/71682493
唤醒方式列表
- URL Schemes
- chrome intent
- ios UniversalLink / android appLink
常见唤醒媒介
- iframe
- a 标签
- window.location
URL Scheme
组成
[scheme:][//authority][path][?query]
比如:tuyasmart://home?test=1
是什么
URL Schemes
可以理解为一种特殊的URL用来定位一个应用以及应用内的某个功能,类比网页链接便很容易理解
Schemes
表示的是URL中的一个位置 - 最初始的位置,既://
之前的字符,比如https://www.apple.com
的Schemes
就是https
通过URL Schemes
, 我们就可以像定位一个网页一样,定位一个应用甚至应用内的某个具体的功能。而定位是哪个应用的,就是Schemes
部分。比如短信应用的Schemes
就是: sms
我们完全可以按照理解一个网页的URL来理解一个应用的URL
| | 网页(苹果)| 应用(微信)| | 网站首页/打开应用 | https://www.apple.com | weixin:// | | 子页面/具体功能 | https://www.apple.com/mac (Mac应用页) | weixin://dl/moments(朋友圈)|
注意点 - 应用是否支持URL Schemes
要看App开发者有没有写那部分的代码了 - URL Schemes
不唯一
使用
使用方式十分简单,就像我们打开一个链接一样,常见的有
- location.href
- iframe
- a标签
使用中常见问题及解决方案
- 可能会被app禁掉,比如微信,qq等
- ios9+ 禁止掉了iframe方式。
- ios及部分安卓浏览器会提示用户是否打开App,并且ios在未安装对应App的时候,会提示“打不开网页,因为该网址无效”
- h5无法感知是否唤醒成功
- 大部分浏览器需要用户手动触发链接,js自动触发无效
针对被app禁止掉的情况,通常会判断是否微信等app环境,然后提示用户浏览器内打开 针对ios9+ iframe
被禁掉的情况,判断下ios版本 针对h5无法感知是否唤醒成功的解决办法是,一段时间之后自动跳转下载页,或者是依赖setTimeout在浏览器进入后台后进程切换导致的时间延迟判断。
2,html和app交互的jssdk的源码
在app中打开的页面是可以使用 url scheme跳转或者请求app的
var noop, MediaCloudJSSDK, Event, TransStatusWatch, onload; noop = function () {}; EipiJSSDK = function () { var iframe, self = this; this.debug = false; this._shakeEnable = false; this._event = new Event(); this._request = function (method, params) { var src = 'cloudjs://' + method, copyParams = {}; for (var k in params) { copyParams[k] = params[k]; } if (copyParams) { for (var key in copyParams) { if (copyParams.hasOwnProperty(key)) { if('thumbs' == key){ var _thumbs=[]; for(var i=0;i<copyParams[key].length;i++){ _thumbs.push(encodeURIComponent(copyParams[key][i])) } copyParams[key]=_thumbs; }else if('url' == key){ copyParams[key] = decodeURIComponent(copyParams[key]) }else{ copyParams[key] = encodeURIComponent(copyParams[key]); } } } src += '?params=' + JSON.stringify(copyParams); } iframe.src = src; self._event.trigger('request'); }; this._callback = function (res) { if (+res.errId !== 0) { self._event.trigger('error', res.errId); if (self.debug) { alert('errId:' + res.errId); } return; } self._event.trigger(res.method, res.data); }; this._transStatusWatch = new TransStatusWatch(this._event); iframe = document.createElement('iframe'); iframe.style.position = 'fixed'; iframe.style.left = '-9999px'; iframe.style.width = '0'; iframe.style.height = '0'; if(document.body){ document.body.appendChild(iframe); }else{ var onload = window.onload || function(){}; window.onload = function(){ document.body.appendChild(iframe); onload(); } } }; Event = function () { var _events = {}, self = this; this.on = function (name, func) { var name = name.toLocaleLowerCase().split('.'); type = name[1] || 'default'; name = name[0]; if (!_events[name]) { _events[name] = []; } _events[name].push({ type: type, func: func }); return self; }; this.off = function (name) { var i, name = name.toLocaleLowerCase().split('.'); type = name[1] || 'default'; name = name[0]; if (_events[name] && _events[name].length) { for (i in _events) { if (i !== name) continue; _events[i] = _events[i].filter(function (key, item) { return (type && type !== key); }); if (_events[i].length) { delete _events[i]; } } } return self; }; this.trigger = function (name, data) { var i, l; name = name.toLocaleLowerCase(); if (!_events[name]) return; for (l = _events[name].length, i = l - 1; i >= 0; i--) { _events[name][i].func.call(null, data); } return self; }; }; TransStatusWatch = function (event) { var callbacks = {}; event.on('transStatusQuery', function (data) { if (typeof callbacks[data.id] !== 'function') { return; } callbacks[data.id]({ status: data.status }); delete(callbacks[data.id]); }) this.add = function (id, func) { callbacks[id] = func; } } /** * 使用率较高的事件绑定函数 */ function normalEventBind(event, name, callback) { event .off(name) .on(name, function (res) { callback(res); event.off(name); }); } /** * 获取用户登陆信息 * @constructor * @param {Function} callback */ EipiJSSDK.prototype.userGetInfo = function (callback) { normalEventBind(this._event, 'userGetInfo', callback); this._request('userGetInfo'); };
3,app使用wenbview支持js接口
参考: https://blog.csdn.net/weixin_40998254/article/details/89211882