IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> H5通过打开小程序的坑 -> 正文阅读

[移动开发]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就是我自己简单改了改原来的,我的能跑起来,能打开任意地址,不能用的自己想办法了


<html>
  <head>
    <title>打开小程序</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1">
    <script>
      window.onerror = e => {
        console.error(e)
        alert('发生错误' + e)
      }
    </script>
    <!-- weui 样式 -->
    <link rel="stylesheet" href="https://res.wx.qq.com/open/libs/weui/2.4.1/weui.min.css"></link>
    <!-- 调试用的移动端 console -->
    <!-- <script src="https://cdn.jsdelivr.net/npm/eruda"></script> -->
    <!-- <script>eruda.init();</script> -->
    <!-- 公众号 JSSDK -->
    <script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
    <!-- 云开发 Web SDK -->
    <script src="https://res.wx.qq.com/open/js/cloudbase/1.1.0/cloud.js"></script>
    <script>
      function docReady(fn) {
        if (document.readyState === 'complete' || document.readyState === 'interactive') {
          fn()
        } else {
          document.addEventListener('DOMContentLoaded', fn);
        }
      }

      /**
       *  @desc  获取url参数
       *  @param  {String} url为穿过来的链接
       *  @param  {String} id为参数名
       */
      function GetParam(url, id) {
        url = url+ "";
        regstr = "/(\\?|\\&)" + id + "=([^\\&]+)/";
        reg = eval(regstr);
        //eval可以将 regstr字符串转换为 正则表达式
        result = url.match(reg);
        if (result && result[2]) {
            return result[2];
        }
      }

      docReady(async function() {
        var ua = navigator.userAgent.toLowerCase()
        var isWXWork = ua.match(/wxwork/i) == 'wxwork'
        var isWeixin = !isWXWork && ua.match(/micromessenger/i) == 'micromessenger'
        var isMobile = false
        var isDesktop = false
        try {
          // 获取url参数path
          window.miniPath = decodeURIComponent(GetParam(window.location.href, "path"))||"";
		  if(window.miniPath=="undefined"){
		  window.miniPath="";
		  }
		  console.error(window.miniPath,window.miniPath.split("?"));
        } catch (error) {
          console.log(error);
          window.miniPath = '/pages/index/index';
        }
        if (navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|IEMobile)/i)) {
          isMobile = true
        } else {
          isDesktop = true
        }

        var containerEl = document.getElementById('wechat-web-container')
        if (isWeixin&&false) {
          var containerEl = document.getElementById('wechat-web-container')
          containerEl.classList.remove('hidden')
          containerEl.classList.add('full', 'wechat-web-container')

          var launchBtn = document.getElementById('launch-btn')
          launchBtn.addEventListener('ready', function (e) {
            launchBtn.setAttribute("path", miniPath);
            console.log('开放标签 ready',launchBtn,)
          })
          launchBtn.addEventListener('launch', function (e) {
            console.log('开放标签 success')
          })
          launchBtn.addEventListener('error', function (e) {
            console.log('开放标签 fail', e.detail)
          })

          wx.config({
            // debug: true, // 调试时可开启
            appId: '自己改', // <!-- replace -->
            timestamp: 0, // 必填,填任意数字即可
            nonceStr: 'nonceStr', // 必填,填任意非空字符串即可
            signature: 'signature', // 必填,填任意非空字符串即可
            jsApiList: ['chooseImage'], // 必填,随意一个接口即可 
            openTagList:['wx-open-launch-weapp'], // 填入打开小程序的开放标签名
          })
        } else if (isDesktop) {
          // 在 pc 上则给提示引导到手机端打开
          var containerEl = document.getElementById('desktop-web-container')
          containerEl.classList.remove('hidden')
          containerEl.classList.add('full', 'desktop-web-container')
        }  else {
          var containerEl = document.getElementById('public-web-container')
          containerEl.classList.remove('hidden')
          containerEl.classList.add('full', 'public-web-container')
          var c = new cloud.Cloud({
            // 必填,表示是未登录模式
            identityless: true,
            // 资源方 AppID
            resourceAppid: '自己改', // <!-- replace -->
            // 资源方环境 ID
            resourceEnv: '自己改', // <!-- replace -->
          })
          await c.init()
          window.c = c

          var buttonEl = document.getElementById('public-web-jump-button')
          var buttonLoadingEl = document.getElementById('public-web-jump-button-loading')
          try {
            await openWeapp(() => {
              buttonEl.classList.remove('weui-btn_loading')
              buttonLoadingEl.classList.add('hidden')
            })
          } catch (e) {
            buttonEl.classList.remove('weui-btn_loading')
            buttonLoadingEl.classList.add('hidden')
            throw e
          }
        }
      })

      async function openWeapp(onBeforeJump) {
        if (window.openlink) {
          return location.href = window.openlink;
        }
        try {
          if (window.miniPath && window.miniPath.includes('?')) {
		  let temp=window.miniPath.split('?');
            var path = temp[0];
			temp.shift();
            var query = temp.join("?");
          }
		  console.error(path,query);
          var c = window.c
          const res = await c.callFunction({
            name: 'public',
            data: {
              action: 'getUrlScheme',
              options: {
                miniPath: (path || window.miniPath)|| "pages/index/index",
                miniQuery: query || ''
              }
            },
          })
          console.error(JSON.stringify(res));
          if (onBeforeJump) {
            onBeforeJump()
          }
          if (res.result.openlink) {
            window.openlink = res.result.openlink
          }
          location.href = window.openlink || res.result.openlink;
        } catch (error) {
          console.log(error);
        }
      }
    </script>
    <style>
      .hidden {
        display: none;
      }

      .full {
        position: absolute;
        top: 0;
        bottom: 0;
        left: 0;
        right: 0;
      }

      .public-web-container {
        display: flex;
        flex-direction: column;
        align-items: center;
      }

      .public-web-container p {
        position: absolute;
        top: 40%;
      }

      .public-web-container a {
        position: absolute;
        bottom: 40%;
      }

      .wechat-web-container {
        display: flex;
        flex-direction: column;
        align-items: center;
      }

      .wechat-web-container p {
        position: absolute;
        top: 40%;
      }

      .wechat-web-container wx-open-launch-weapp {
        position: absolute;
        bottom: 40%;
        left: 0;
        right: 0;
        display: flex;
        flex-direction: column;
        align-items: center;
      }

      .desktop-web-container {
        display: flex;
        flex-direction: column;
        align-items: center;
      }

      .desktop-web-container p {
        position: absolute;
        top: 40%;
      }
    </style>
  </head>
  <body>
    <div class="page full">
      <div id="public-web-container" class="hidden">
        <p class="">正在打开 “小程序”...</p> <!-- replace -->
        <a id="public-web-jump-button" href="javascript:" class="weui-btn weui-btn_primary weui-btn_loading" onclick="openWeapp()">
          <span id="public-web-jump-button-loading" class="weui-primary-loading weui-primary-loading_transparent"><i class="weui-primary-loading__dot"></i></span>
          打开小程序
        </a>
      </div>
      <div id="wechat-web-container" class="hidden">
        <p class="">点击以下按钮打开 “小程序”</p> <!-- replace -->
        <!-- 跳转小程序的开放标签。文档 https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_Open_Tag.html -->
        <wx-open-launch-weapp id="launch-btn" username="自己改" path="pages/index/index"> <!-- replace -->
          <template>
            <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>
          </template>
        </wx-open-launch-weapp>
      </div>
      <div id="desktop-web-container" class="hidden">
        <p class="">请在手机打开网页链接</p>
      </div>
    </div>
  </body>
</html>
// 云函数入口文件
const cloud = require('wx-server-sdk')

cloud.init()

// 云函数入口函数
exports.main = async (event, context) => {
  const wxContext = cloud.getWXContext()

  switch (event.action) {
    case 'getUrlScheme': {
      return getUrlScheme(event.options)
    }
  }

  return 'action not found'
}

async function getUrlScheme(options) {
  options=options||{};
  let miniQuery=options.miniQuery||"";
  if(miniQuery.indexOf("src=")!=-1){
    miniQuery = "src=" + encodeURIComponent(miniQuery.replace("src=",""));
  }
  
  
  var temp=await cloud.openapi.urlscheme.generate({
    jumpWxa: {
      path: options.miniPath||'/pages/index/index', // <!-- replace -->
      query: miniQuery,
    },
    // 如果想不过期则置为 false,并可以存到数据库
    isExpire: true,
    // 一分钟有效期
    expireTime: parseInt(Date.now() / 1000 + 60),
  })
  return {...temp,...options,a:miniQuery};
  return {wx_data:temp,options}
}

然后我又去看了看服务端生成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这不是折腾人吗?还是一个链接就能解决了,真尼玛折腾人

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-09-21 00:40:22  更:2022-09-21 00:40:57 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 4:56:09-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码