Note-51408-25

Token ID: 1

ERC-721 1 Transfers

Metadata

{
  "title": "URL Scheme到底应该怎么跳转",
  "tags": [
    "post"
  ],
  "summary": "什么是URL Scheme 在现代URL协议中,除了在浏览器里常见的http协议,还有一类URL叫URL Scheme,形如这样的一些链接:\n\nalipayqr://platformapi/startapp?saId=10000007 打开支付宝扫一扫 weixin…",
  "sources": [
    "xlog"
  ],
  "external_urls": [
    "https://outti.me/about_url_scheme"
  ],
  "date_published": "2023-04-12T03:27:24.706Z",
  "content": "## 什么是URL Scheme\n在现代URL协议中,除了在浏览器里常见的`http`协议,还有一类URL叫`URL Scheme`,形如这样的一些链接:\n- alipayqr://platformapi/startapp?saId=10000007 打开支付宝扫一扫\n- weixin://scanqrcode 打开微信扫一扫\n\n常见的URL Scheme你可以在网上搜到,这里我找到一份[常见 iOS App URL Scheme](https://gist.github.com/zhuziyi1989/3f96a73c45a87778b560e44cb551ebd2 \"常见 iOS App URL Scheme\")\n\n\n它们的“`协议头`”是由App自己定义的。这些URL在得到正确的处理后就会携带URL内容打开并传递给对应的App,常见的打开方法有:浏览器以及手机上自带的扫一扫功能。\n\n`URL Scheme`是`URL`吗?当然是,它也有和http url差不多的特性,比如支持`GET`参数。通过这种方式,能够实现将参数携带给目标App去处理。\n\n![在浏览器中访问URL Scheme就可以打开](ipfs://bafkreidwu6d4n3h3daiwb2zqo4o4f4piceeyvaln3rv557dtzdxtfk5uqe)\n> 在浏览器中访问URL Scheme就可以打开\n\n### 那有什么用?\n利用它,可以实现在不同App之前跳转。虽然现在网页技术很成熟了,但是`Native`应用不能直接搬到浏览器里运行,有些必须使用到的API实在是没有提供支持(例如网页上读取NFC信息),再或者运营多一个平台成本太高,划不来。\n\n所以很多别人分享给你的App链接,打开后第一件事情就是让你:**在“App”中打开此页?** 如果你不这么做,你可能得到一个压根不能用的网页版本:\n\n![image](ipfs://bafkreidd35ybqlqt4laoui2zcdwzclmqfypoyjrykxjo5ajndpibp2co6q)\n\n![image](ipfs://bafybeidxwo2yuy33cyxm2d7tyhhzm2iipxcjcyqgs6sj24wrj6zwmo3ez4)\n\n> 今天这个App你必须给我打开!!\n\n由于国家出手整治,现在强制使用App的情况少了很多。搞个障眼法限制一下功能而已,一张图有三个地方在暗示你打开App。\n\n整治前呢?流氓到你搜索图片,强制让你用App才能看结果..(不点名了,用过的都有数)\n\n---\n\n这么坏?那有这个东西干什么?那肯定是有需求才被制造出来的。比如在网页里买东西付款的时候,快捷登陆网页的时候;网页并没有办法取得你手机里App存储的信息,而你也不希望在网页上又重复输入一遍那总是忘记的密码,甚至盘问你所有的安全信息吧?\n\n所以这个东西只能是有利有弊,在国家出手后,我认为这个利会慢慢**持平**的。\n\n## 交互中怎么跳转比较好?\n那如果这个`URL Scheme`我需要用,怎么才能让我在网页里实现不了的功能引导用户打开App去使用呢?\n## URL Scheme跳转的几种方式\n前面介绍过了,`URL Scheme`其实本质上还是`URL`,那么正常打开链接的方法都能用:\n- a标签\n- 使用js创建iframe\n```js\nvar iframe = document.createElement('iframe');\niframe.style.display = 'none';\niframe.src = url;\ndocument.body.appendChild(iframe);\n```\n- 使用js跳转\n```\nwindow.location.href = url;\n```\n\n不过前面也提到了,`URL Scheme`是需要App主动注册的,App都没装怎么办?那打开就会像这样:\n\n![image](ipfs://bafkreiakdgamyz3vzm325eonq46qnjvaxxnggetku7fdhs6hf4dmxo3t3u)\n\n### 怎么判断是否成功跳转\n> 题外话,还有一种`Universal Link`,能够让系统和浏览器主动帮你完成判断对应App是否打开的事情。不过,仅限在**Apple设备上**\n\n由于访问url是单向的,并不\n会给予程序任何反馈,所以我们只能从一些其他现象来判断是否成功打开:\n![image](ipfs://bafybeifrer2hmemqmbbbygj4kjvz5mfp6m7iwliwckhiuskmblkux6kz6q)\n\n来源 [各种场景唤起 App 骚操作](https://juejin.cn/post/6844903993152372749 \"各种场景唤起 App 骚操作\")\n\n常用的是**定时器**法,原理就是跳转App后,浏览器中的JS线程有可能会被暂停,这个时候“时间就不走了”,而没有安装App则有可能留在原来的网页不动,从而判断并没有成功打开URL Scheme,进而进行后续的逻辑。\n\n不过代码看起来实在是复杂,兼容性做的很足,能不能简化一下?\n```js\n\nvar work = false;\nwindow.location.href = \"URL Scheme\"\nwindow.onblur=function(){work = true;}\nwindow.setTimeout(function(){\n  if(!work){\n    打开失败的逻辑,比如:\n    window.location.href = \"下一步的链接\"\n  }\n},1000)\n\n```\n这个是我试着写出来的,不过正如上面的文章所说,**需要考虑不同机型的唤起速度**,我这里固定**1秒**,体验上来说不会很久页面才会有进一步的动作。\n\n不过你可能也发现了,同样是判断页面有没有失去焦点,但是如果URL Scheme是无效的,在Safari浏览器中也会弹个窗,那这样子处理反而会导致没有安装App的用户也不能得到正确的反馈。\n\n当然这个事情因不同平台而已,就我实际测试,相当一部分的App内置浏览器/安卓自带浏览器,在遇到不认识的URL Scheme时是不会有任何反馈的。\n\n那么本着**宁可错杀一千不放过一个**,在实际业务里应该这么用:\n```js\nwindow.location.href = \"URL Scheme\"\nwindow.setTimeout(function(){\n  打开失败的逻辑,比如:\n  window.location.href = \"下一步的链接\"\n},1000)\n```\n还需要等待,是为了让能够跳转的用户视觉上看起来没那么割裂(弹窗的底下还有东西在加载)\n\n**支持 Universal Link 大力发展!**\n\n**拒绝流氓行为 强制跳转App使用基本功能!**",
  "attributes": [
    {
      "value": "about_url_scheme",
      "trait_type": "xlog_slug"
    }
  ]
}