• H5通过打开小程序的坑


    哎,微信开发真的是一言难尽,全是问题

    先看几个文档吧:

    获取scheme码 | 微信开放文档微信开发者平台文档https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/qrcode-link/url-scheme/generateScheme.html静态网站 H5 跳小程序 | 微信开放文档微信开发者平台文档https://developers.weixin.qq.com/miniprogram/dev/wxcloud/guide/staticstorage/jump-miniprogram.html我的第一个云函数 | 微信开放文档微信开发者平台文档https://developers.weixin.qq.com/miniprogram/dev/wxcloud/guide/functions/getting-started.html

    h5打开小程序大体分为两种:

    1、微信内环境

    2、微信外环境

    这里我只讨论微信外环境

    之前微信小程序后台这个工具呢是有一个生成 urlscheme 的,现在这个工具入口已经被关闭了,其实之前这个工具贼好用,一个表单,自己填一下地址+参数再选个时间就可以生成urlscheme了,但是微信抽风,貌似把urlscheme这个功能做了一部分的阉割,不能再生成永久链接了,后面只能用代码生成了。。功能入口也被关闭了

     大家可以去看这个链接下大家对微信的骂,程序员何必为难程序员呢(误:应该是产品無脑子)小程序链接生成与使用规则调整公告 | 微信开放社区 (qq.com)icon-default.png?t=M85Bhttps://developers.weixin.qq.com/community/develop/doc/000aeab88a4ea0c5c89d81fde5b801?source=templateb&page=2#comment-list

    我们之前很多地址都是通过工具生成的,然后会导致一个什么问题呢:

    比如生成的地址 a, 在微信外环境的时候,用户1点了,用户2再点就会报错,说链接被使用了啥啥啥的,貌似微信内环境还是可以的(记不太清了)

    但是在调整之前,生成地址a是一个通用的,微信外环境的时候任何人都是可以点的。微信内环境也没有问题。

    至于我是怎么发现的:有一天用户反馈app里面的链接都不能打开小程序了,查了一下才知道,噢,弟弟微信又改规则了,如果想做到链接都能打开就得每个人生成不同的链接,你说这种傻比不傻比

    之前app打开小程序真的很简单,生成一个urlscheme,然后让app直接打开外部浏览器,他就会自动打开小程序了,但是现在修改了之后只能通过微信开放平台的文档来做了,app调用sdk里面的接口才能打开小程序了

    其实最开始之前也在研究 云开发托管静态网站这种方式,后面觉得太麻烦了,不用了直接用urlscheme打开方便的很

    直到昨天,发现瑞幸咖啡还能继续打开小程序,大家可以看看。

    打开小程序icon-default.png?t=M85Bhttps://mcloud.lkcoffee.com/jump-mp.html?path=%2Fpages%2Findex%2Fmenu%3Fsource%3DSMS我心想着瑞幸咖啡搞得还挺好,每个人单独生成链接,他一天够吗?

    然后点开看了看,他并不是为每个人单独生成链接的。

    突然想起来 静态网站托管还是能接续的,所以找文档,我也继续弄静态网站托管吧

    坑开始来了。

    Q:云开发入口在哪?

    A:登录你的小程序,入口就有了,我昨天进去是公众号网页,整了半天,总是让我新建云开发环境,我清楚的记得我之前弄过一次的。点了云开发之后,微信开发者工具就会再开一个窗口:“云开发控制台”,变成两个窗口了 1、“微信开发者工具” 2、“云开发控制台”

    开始查看这个文档

    静态网站 H5 跳小程序 | 微信开放文档微信开发者平台文档https://developers.weixin.qq.com/miniprogram/dev/wxcloud/guide/staticstorage/jump-miniprogram.html

     Q:静态网站,我这边没有啥问题,上传,绑定域名,证书都能解决,但是这个云函数怎么创建啊?代码怎么写啊

     

    你看这,创建也没法编辑啊? 

    A:看这个

    我的第一个云函数 | 微信开放文档微信开发者平台文档https://developers.weixin.qq.com/miniprogram/dev/wxcloud/guide/functions/getting-started.html

    这时候回到"微信开发者工具"小程序开发的根目录,找到 project.config.json 这个文件,去 最外层建一个

      "cloudfunctionRoot": "cloudfunctions/",

    就像这样

     这时候回到小程序根目录:自己创建 cloudfunctions 文件夹 然后在“cloudfunctions” 右键

     同步云函数(如果之前有的)

    或者新建云函数,这时候就可以写代码了,把刚才那文档里面的代码拷贝过去,

    最后记得点击 云端安装依赖

     然后这时候我们再去 “云开发控制台” 选中云函数,这时候就有刚才传的 函数了

     确实很懵。

    东西都准备好了,开始写代码吧

    写的时候发现 cloud.openapi.urlscheme.generate 这个函数有个bug

        jumpWxa.query传值,只要  它的值中包含了  ? 它生成的urlscheme打开之后真正的链接就有问题,生成的地址根本打不开

    比如:

    path:"/pages/index/index"

    query : "src%3Dhttps%3A%2F%2Fbaidu.com%2Fp"

    生成的地址就是 "pages/index/index.html?src=https://baidu.com/p"

    如果query : "src%3Dhttps%3A%2F%2Fbaidu.com%2Fp%3Did=1" 只是在后面加了一个?id=1而已

    生成的地址就是 "pages/index/index?src=https://baidu.com/p?id=1.html?"

    至于生成地址我是通过公众号写文章的时候有插入小程序地址这个功能去拿到真正详细的地址的

     当然,也可能是我写的有问题

    现在我把html+js的代码都传上来,有需要的自取,需要改成自己的参数 html基本是用的瑞幸咖啡的,js就是我自己简单改了改原来的,我的能跑起来,能打开任意地址,不能用的自己想办法了

    1. <html>
    2. <head>
    3. <title>打开小程序title>
    4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    5. <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1">
    6. <script>
    7. window.onerror = e => {
    8. console.error(e)
    9. alert('发生错误' + e)
    10. }
    11. script>
    12. <link rel="stylesheet" href="https://res.wx.qq.com/open/libs/weui/2.4.1/weui.min.css">link>
    13. <script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js">script>
    14. <script src="https://res.wx.qq.com/open/js/cloudbase/1.1.0/cloud.js">script>
    15. <script>
    16. function docReady(fn) {
    17. if (document.readyState === 'complete' || document.readyState === 'interactive') {
    18. fn()
    19. } else {
    20. document.addEventListener('DOMContentLoaded', fn);
    21. }
    22. }
    23. /**
    24. * @desc 获取url参数
    25. * @param {String} url为穿过来的链接
    26. * @param {String} id为参数名
    27. */
    28. function GetParam(url, id) {
    29. url = url+ "";
    30. regstr = "/(\\?|\\&)" + id + "=([^\\&]+)/";
    31. reg = eval(regstr);
    32. //eval可以将 regstr字符串转换为 正则表达式
    33. result = url.match(reg);
    34. if (result && result[2]) {
    35. return result[2];
    36. }
    37. }
    38. docReady(async function() {
    39. var ua = navigator.userAgent.toLowerCase()
    40. var isWXWork = ua.match(/wxwork/i) == 'wxwork'
    41. var isWeixin = !isWXWork && ua.match(/micromessenger/i) == 'micromessenger'
    42. var isMobile = false
    43. var isDesktop = false
    44. try {
    45. // 获取url参数path
    46. window.miniPath = decodeURIComponent(GetParam(window.location.href, "path"))||"";
    47. if(window.miniPath=="undefined"){
    48. window.miniPath="";
    49. }
    50. console.error(window.miniPath,window.miniPath.split("?"));
    51. } catch (error) {
    52. console.log(error);
    53. window.miniPath = '/pages/index/index';
    54. }
    55. if (navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|IEMobile)/i)) {
    56. isMobile = true
    57. } else {
    58. isDesktop = true
    59. }
    60. var containerEl = document.getElementById('wechat-web-container')
    61. if (isWeixin&&false) {
    62. var containerEl = document.getElementById('wechat-web-container')
    63. containerEl.classList.remove('hidden')
    64. containerEl.classList.add('full', 'wechat-web-container')
    65. var launchBtn = document.getElementById('launch-btn')
    66. launchBtn.addEventListener('ready', function (e) {
    67. launchBtn.setAttribute("path", miniPath);
    68. console.log('开放标签 ready',launchBtn,)
    69. })
    70. launchBtn.addEventListener('launch', function (e) {
    71. console.log('开放标签 success')
    72. })
    73. launchBtn.addEventListener('error', function (e) {
    74. console.log('开放标签 fail', e.detail)
    75. })
    76. wx.config({
    77. // debug: true, // 调试时可开启
    78. appId: '自己改', //
    79. timestamp: 0, // 必填,填任意数字即可
    80. nonceStr: 'nonceStr', // 必填,填任意非空字符串即可
    81. signature: 'signature', // 必填,填任意非空字符串即可
    82. jsApiList: ['chooseImage'], // 必填,随意一个接口即可
    83. openTagList:['wx-open-launch-weapp'], // 填入打开小程序的开放标签名
    84. })
    85. } else if (isDesktop) {
    86. // 在 pc 上则给提示引导到手机端打开
    87. var containerEl = document.getElementById('desktop-web-container')
    88. containerEl.classList.remove('hidden')
    89. containerEl.classList.add('full', 'desktop-web-container')
    90. } else {
    91. var containerEl = document.getElementById('public-web-container')
    92. containerEl.classList.remove('hidden')
    93. containerEl.classList.add('full', 'public-web-container')
    94. var c = new cloud.Cloud({
    95. // 必填,表示是未登录模式
    96. identityless: true,
    97. // 资源方 AppID
    98. resourceAppid: '自己改', //
    99. // 资源方环境 ID
    100. resourceEnv: '自己改', //
    101. })
    102. await c.init()
    103. window.c = c
    104. var buttonEl = document.getElementById('public-web-jump-button')
    105. var buttonLoadingEl = document.getElementById('public-web-jump-button-loading')
    106. try {
    107. await openWeapp(() => {
    108. buttonEl.classList.remove('weui-btn_loading')
    109. buttonLoadingEl.classList.add('hidden')
    110. })
    111. } catch (e) {
    112. buttonEl.classList.remove('weui-btn_loading')
    113. buttonLoadingEl.classList.add('hidden')
    114. throw e
    115. }
    116. }
    117. })
    118. async function openWeapp(onBeforeJump) {
    119. if (window.openlink) {
    120. return location.href = window.openlink;
    121. }
    122. try {
    123. if (window.miniPath && window.miniPath.includes('?')) {
    124. let temp=window.miniPath.split('?');
    125. var path = temp[0];
    126. temp.shift();
    127. var query = temp.join("?");
    128. }
    129. console.error(path,query);
    130. var c = window.c
    131. const res = await c.callFunction({
    132. name: 'public',
    133. data: {
    134. action: 'getUrlScheme',
    135. options: {
    136. miniPath: (path || window.miniPath)|| "pages/index/index",
    137. miniQuery: query || ''
    138. }
    139. },
    140. })
    141. console.error(JSON.stringify(res));
    142. if (onBeforeJump) {
    143. onBeforeJump()
    144. }
    145. if (res.result.openlink) {
    146. window.openlink = res.result.openlink
    147. }
    148. location.href = window.openlink || res.result.openlink;
    149. } catch (error) {
    150. console.log(error);
    151. }
    152. }
    153. script>
    154. <style>
    155. .hidden {
    156. display: none;
    157. }
    158. .full {
    159. position: absolute;
    160. top: 0;
    161. bottom: 0;
    162. left: 0;
    163. right: 0;
    164. }
    165. .public-web-container {
    166. display: flex;
    167. flex-direction: column;
    168. align-items: center;
    169. }
    170. .public-web-container p {
    171. position: absolute;
    172. top: 40%;
    173. }
    174. .public-web-container a {
    175. position: absolute;
    176. bottom: 40%;
    177. }
    178. .wechat-web-container {
    179. display: flex;
    180. flex-direction: column;
    181. align-items: center;
    182. }
    183. .wechat-web-container p {
    184. position: absolute;
    185. top: 40%;
    186. }
    187. .wechat-web-container wx-open-launch-weapp {
    188. position: absolute;
    189. bottom: 40%;
    190. left: 0;
    191. right: 0;
    192. display: flex;
    193. flex-direction: column;
    194. align-items: center;
    195. }
    196. .desktop-web-container {
    197. display: flex;
    198. flex-direction: column;
    199. align-items: center;
    200. }
    201. .desktop-web-container p {
    202. position: absolute;
    203. top: 40%;
    204. }
    205. style>
    206. head>
    207. <body>
    208. <div class="page full">
    209. <div id="public-web-container" class="hidden">
    210. <p class="">正在打开 “小程序”...p>
    211. <a id="public-web-jump-button" href="javascript:" class="weui-btn weui-btn_primary weui-btn_loading" onclick="openWeapp()">
    212. <span id="public-web-jump-button-loading" class="weui-primary-loading weui-primary-loading_transparent"><i class="weui-primary-loading__dot">i>span>
    213. 打开小程序
    214. a>
    215. div>
    216. <div id="wechat-web-container" class="hidden">
    217. <p class="">点击以下按钮打开 “小程序”p>
    218. <wx-open-launch-weapp id="launch-btn" username="自己改" path="pages/index/index">
    219. <template>
    220. <button style="width: 200px; height: 45px; text-align: center; font-size: 17px; display: block; margin: 0 auto; padding: 8px 24px; border: none; border-radius: 4px; background-color: #07c160; color:#fff;">打开小程序button>
    221. template>
    222. wx-open-launch-weapp>
    223. div>
    224. <div id="desktop-web-container" class="hidden">
    225. <p class="">请在手机打开网页链接p>
    226. div>
    227. div>
    228. body>
    229. html>
    1. // 云函数入口文件
    2. const cloud = require('wx-server-sdk')
    3. cloud.init()
    4. // 云函数入口函数
    5. exports.main = async (event, context) => {
    6. const wxContext = cloud.getWXContext()
    7. switch (event.action) {
    8. case 'getUrlScheme': {
    9. return getUrlScheme(event.options)
    10. }
    11. }
    12. return 'action not found'
    13. }
    14. async function getUrlScheme(options) {
    15. options=options||{};
    16. let miniQuery=options.miniQuery||"";
    17. if(miniQuery.indexOf("src=")!=-1){
    18. miniQuery = "src=" + encodeURIComponent(miniQuery.replace("src=",""));
    19. }
    20. var temp=await cloud.openapi.urlscheme.generate({
    21. jumpWxa: {
    22. path: options.miniPath||'/pages/index/index', //
    23. query: miniQuery,
    24. },
    25. // 如果想不过期则置为 false,并可以存到数据库
    26. isExpire: true,
    27. // 一分钟有效期
    28. expireTime: parseInt(Date.now() / 1000 + 60),
    29. })
    30. return {...temp,...options,a:miniQuery};
    31. return {wx_data:temp,options}
    32. }

    然后我又去看了看服务端生成urlscheme的文档,发现,gr的又将规则改回来了

     

    小程序链接生成与使用规则调整公告 | 微信开放社区 (qq.com)icon-default.png?t=M85Bhttps://developers.weixin.qq.com/community/develop/doc/000aeab88a4ea0c5c89d81fde5b801?source=templateb&page=1#comment-list获取scheme码 | 微信开放文档微信开发者平台文档https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/qrcode-link/url-scheme/generateScheme.html第一个就是官方发的公告,第二个是最新的文档,而且我翻了翻公告,啥时候调整回来的,官方也没有说,那么问题来了,为啥小程序后台的工具入口没有恢复呢?

    小程序官方公告 | 微信开放社区 (qq.com)icon-default.png?t=M85Bhttps://developers.weixin.qq.com/community/develop/list/2?id=

     tmd这不是折腾人吗?还是一个链接就能解决了,真尼玛折腾人

  • 相关阅读:
    关于数组太大导致stack over flow
    Spring5应用之AOP注解编程
    BSN专网正式进入欧洲市场,推动全球公有云分布式进程
    4507. 子数组异或和
    科技云报道:云安全的新战场上,如何打破“云威胁”的阴霾?
    跑在笔记本里的大语言模型 - GPT4All
    3D感知(二):单目3D物体检测
    【我的两周年创作纪念日】
    KubeEdge 边缘计算应用部署
    环境变量的参数
  • 原文地址:https://blog.csdn.net/u010067685/article/details/126872634