- wx.request 请求封装有实现的小伙伴吗?
有没有觉得微信原生的wx.request的这个太繁琐了,每次都要写一大堆,为了后面书写方便完全可以进行二次封装,但我在封装的时候发现有些问题,例如我想封装成这样: app.post(app.requestBasePath + "后端请求地址",params).success(function(data){ }); 可以吗?
2018-03-14 - 一个通用request的封装
小程序内置了[代码]wx.request[代码],用于向后端发送请求,我们先来看看它的文档: wx.request(OBJECT) 发起网络请求。使用前请先阅读说明。 OBJECT参数说明: 参数名 类型 必填 默认值 说明 最低版本 url String 是 - 开发者服务器接口地址 - data Object/String/ArrayBuffer 否 - 请求的参数 - header Object 否 - 设置请求的 header,header 中不能设置 Referer。 - method String 否 GET (需大写)有效值:OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT - dataType String 否 json 如果设为json,会尝试对返回的数据做一次 JSON.parse - responseType String 否 text 设置响应的数据类型。合法值:text、arraybuffer 1.7.0 success Function 否 - 收到开发者服务成功返回的回调函数 - fail Function 否 - 接口调用失败的回调函数 - complete Function 否 - 接口调用结束的回调函数(调用成功、失败都会执行) - success返回参数说明: 参数 类型 说明 最低版本 data Object/String/ArrayBuffer 开发者服务器返回的数据 - statusCode Number 开发者服务器返回的 HTTP 状态码 - header Object 开发者服务器返回的 HTTP Response Header 1.2.0 这里我们主要看两点: 回调函数:success、fail、complete; success的返回参数:data、statusCode、header。 相对于通过入参传回调函数的方式,我更喜欢promise的链式,这是我期望的第一个点;success的返回参数,在实际开发过程中,我只关心data部分,这里可以做一下处理,这是第二点。 promisify 小程序默认支持promise,所以这一点改造还是很简单的: [代码]/** * promise请求 * 参数:参考wx.request * 返回值:[promise]res */ function requestP(options = {}) { const { success, fail, } = options; return new Promise((res, rej) => { wx.request(Object.assign( {}, options, { success: res, fail: rej, }, )); }); } [代码] 这样一来我们就可以使用这个函数来代替wx.request,并且愉快地使用promise链式: [代码]requestP({ url: '/api', data: { name: 'Jack' } }) .then((res) => { console.log(res); }) .catch((err) => { console.log(err); }); [代码] 注意,小程序的promise并没有实现finally,Promise.prototype.finally是undefined,所以complete不能用finally代替。 精简返回值 精简返回值也是很简单的事情,第一直觉是,当请求返回并丢给我一大堆数据时,我直接resolve我要的那一部分数据就好了嘛: [代码]return new Promise((res, rej) => { wx.request(Object.assign( {}, options, { success(r) { res(r.data); // 这里只取data }, fail: rej, }, )); }); [代码] but!这里需要注意,我们仅仅取data部分,这时候默认所有success都是成功的,其实不然,wx.request是一个基础的api,fail只发生在系统和网络层面的失败情况,比如网络丢包、域名解析失败等等,而类似404、500之类的接口状态,依旧是调用success,并体现在[代码]statusCode[代码]上。 从业务上讲,我只想处理json的内容,并对json当中的相关状态进行处理;如果一个接口返回的不是约定好的json,而是类似404、500之类的接口异常,我统一当成接口/网络错误来处理,就像jquery的ajax那样。 也就是说,如果我不对[代码]statusCode[代码]进行区分,那么包括404、500在内的所有请求结果都会走[代码]requestP().then[代码],而不是[代码]requestP().catch[代码]。这显然不是我们熟悉的使用方式。 于是我从jquery的ajax那里抄来了一段代码。。。 [代码]/** * 判断请求状态是否成功 * 参数:http状态码 * 返回值:[Boolen] */ function isHttpSuccess(status) { return status >= 200 && status < 300 || status === 304; } [代码] [代码]isHttpSuccess[代码]用来决定一个http状态码是否判为成功,于是结合[代码]requestP[代码],我们可以这么来用: [代码]return new Promise((res, rej) => { wx.request(Object.assign( {}, options, { success(r) { const isSuccess = isHttpSuccess(r.statusCode); if (isSuccess) { // 成功的请求状态 res(r.data); } else { rej({ msg: `网络错误:${r.statusCode}`, detail: r }); } }, fail: rej, }, )); }); [代码] 这样我们就可以直接resolve返回结果中的data,而对于非成功的http状态码,我们则直接reject一个自定义的error对象,这样就是我们所熟悉的ajax用法了。 登录 我们经常需要识别发起请求的当前用户,在web中这通常是通过请求中携带的cookie实现的,而且对于前端开发者是无感知的;小程序中没有cookie,所以需要主动地去补充相关信息。 首先要做的是:登录。 通过[代码]wx.login[代码]接口我们可以得到一个[代码]code[代码],调用后端登录接口将code传给后端,后端再用code去调用微信的登录接口,换取[代码]sessionKey[代码],最后生成一个[代码]sessionId[代码]返回给前端,这就完成了登录。 [图片] 具体参考微信官方文档:wx.login [代码]const apiUrl = 'https://jack-lo.github.io'; let sessionId = ''; /** * 登录 * 参数:undefined * 返回值:[promise]res */ function login() { return new Promise((res, rej) => { // 微信登录 wx.login({ success(r1) { if (r1.code) { // 获取sessionId requestP({ url: `${apiUrl}/api/login`, data: { code: r1.code, }, method: 'POST' }) .then((r2) => { if (r2.rcode === 0) { const { sessionId } = r2.data; // 保存sessionId sessionId = sessionId; res(r2); } else { rej({ msg: '获取sessionId失败', detail: r2 }); } }) .catch((err) => { rej(err); }); } else { rej({ msg: '获取code失败', detail: r1 }); } }, fail: rej, }); }); } [代码] 好的,我们做好了登录并且顺利获取到了sessionId,接下来是考虑怎么把sessionId通过请求带上去。 sessionId 为了将状态与数据区分开来,我们决定不通过data,而是通过header的方式来携带sessionId,我们对原本的requestP稍稍进行修改,使得它每次调用都自动在header里携带sessionId: [代码]function requestP(options = {}) { const { success, fail, } = options; // 统一注入约定的header let header = Object.assign({ sessionId: sessionId }, options.header); return new Promise((res, rej) => { ... }); } [代码] 好的,现在请求会自动带上sessionId了; 但是,革命尚未完成: 我们什么时候去登录呢?或者说,我们什么时候去获取sessionId? 假如还没登录就发起请求了怎么办呢? 登录过期了怎么办呢? 我设想有这样一个逻辑: 当我发起一个请求的时候,如果这个请求不需要sessionId,则直接发出; 如果这个请求需要携带sessionId,就去检查现在是否有sessionId,有的话直接携带,发起请求; 如果没有,自动去走登录的流程,登录成功,拿到sessionId,再去发送这个请求; 如果有,但是最后请求返回结果是sessionId过期了,那么程序自动走登录的流程,然后再发起一遍。 其实上面的那么多逻辑,中心思想只有一个:都是为了拿到sessionId! 我们需要对请求做一层更高级的封装。 首先我们需要一个函数专门去获取sessionId,它将解决上面提到的2、3点: [代码]/** * 获取sessionId * 参数:undefined * 返回值:[promise]sessionId */ function getSessionId() { return new Promise((res, rej) => { // 本地sessionId缺失,重新登录 if (!sessionId) { login() .then((r1) => { res(r1.data.sessionId); }) .catch(rej); } } else { res(sessionId); } }); } [代码] 好的,接下来我们解决第1、4点,我们先假定:sessionId过期的时候,接口会返回[代码]code=401[代码]。 整合了getSessionId,得到一个更高级的request方法: [代码]/** * ajax高级封装 * 参数:[Object]option = {},参考wx.request; * [Boolen]keepLogin = false * 返回值:[promise]res */ function request(options = {}, keepLogin = true) { if (keepLogin) { return new Promise((res, rej) => { getSessionId() .then((r1) => { // 获取sessionId成功之后,发起请求 requestP(options) .then((r2) => { if (r2.rcode === 401) { // 登录状态无效,则重新走一遍登录流程 // 销毁本地已失效的sessionId sessionId = ''; getSessionId() .then((r3) => { requestP(options) .then(res) .catch(rej); }); } else { res(r2); } }) .catch(rej); }) .catch(rej); }); } else { // 不需要sessionId,直接发起请求 return requestP(options); } } [代码] 留意req的第二参数keepLogin,是为了适配有些接口不需要sessionId,但因为我的业务里大部分接口都需要登录状态,所以我默认值为true。 这差不多就是我们封装request的最终形态了。 并发处理 这里其实我们还需要考虑一个问题,那就是并发。 试想一下,当我们的小程序刚打开的时候,假设页面会同时发出5个请求,而此时没有sessionId,那么,这5个请求按照上面的逻辑,都会先去调用login去登录,于是乎,我们就会发现,登录接口被同步调用了5次!并且后面的调用将导致前面的登录返回的sessionId过期~ 这bug是很严重的,理论上来说,登录我们只需要调用一次,然后一直到过期为止,我们都不需要再去登录一遍了。 ——那么也就是说,同一时间里的所有接口其实只需要登录一次就可以了。 ——也就是说,当有登录的请求发出的时候,其他那些也需要登录状态的接口,不需要再去走登录的流程,而是等待这次登录回来即可,他们共享一次登录操作就可以了! 解决这个问题,我们需要用到队列。 我们修改一下getSessionId这里的逻辑: [代码]const loginQueue = []; let isLoginning = false; /** * 获取sessionId * 参数:undefined * 返回值:[promise]sessionId */ function getSessionId() { return new Promise((res, rej) => { // 本地sessionId缺失,重新登录 if (!sessionId) { loginQueue.push({ res, rej }); if (!isLoginning) { isLoginning = true; login() .then((r1) => { isLoginning = false; while (loginQueue.length) { loginQueue.shift().res(r1); } }) .catch((err) => { isLoginning = false; while (loginQueue.length) { loginQueue.shift().rej(err); } }); } } else { res(sessionId); } }); } [代码] 使用了isLoginning这个变量来充当锁的角色,锁的目的就是当登录正在进行中的时候,告诉程序“我已经在登录了,你先把回调都加队列里去吧”,当登录结束之后,回来将锁解开,把回调全部执行并清空队列。 这样我们就解决了问题,同时提高了性能。 封装 在做完以上工作以后,我们都很清楚的封装结果就是[代码]request[代码],所以我们把request暴露出去就好了: [代码]function request() { ... } module.exports = request; [代码] 这般如此之后,我们使用起来就可以这样子: [代码]const request = require('request.js'); Page({ ready() { // 获取热门列表 request({ url: 'https://jack-lo.github.io/api/hotList', data: { page: 1 } }) .then((res) => { console.log(res); }) .catch((err) => { console.log(err); }); // 获取最新信息 request({ url: 'https://jack-lo.github.io/api/latestList', data: { page: 1 } }) .then((res) => { console.log(res); }) .catch((err) => { console.log(err); }); }, }); [代码] 是不是很方便,可以用promise的方式,又不必关心登录的问题。 然而可达鸭眉头一皱,发现事情并不简单,一个接口有可能在多个地方被多次调用,每次我们都去手写这么一串[代码]url[代码]参数,并不那么方便,有时候还不好找,并且容易出错。 如果能有个地方专门记录这些url就好了;如果每次调用接口,都能像调用一个函数那么简单就好了。 基于这个想法,我们还可以再做一层封装,我们可以把所有的后端接口,都封装成一个方法,调用接口就相对应调用这个方法: [代码]const apiUrl = 'https://jack-lo.github.io'; const req = { // 获取热门列表 getHotList(data) { const url = `${apiUrl}/api/hotList` return request({ url, data }); }, // 获取最新列表 getLatestList(data) { const url = `${apiUrl}/api/latestList` return request({ url, data }); } } module.exports = req; // 注意这里暴露的已经不是request,而是req [代码] 那么我们的调用方式就变成了: [代码]const req = require('request.js'); Page({ ready() { // 获取热门列表 req.getHotList({ page: 1 }) .then((res) => { console.log(res); }) .catch((err) => { console.log(err); }); // 获取最新信息 req.getLatestList({ page: 1 }) .then((res) => { console.log(res); }) .catch((err) => { console.log(err); }); } }); [代码] 这样一来就方便了很多,而且有一个很大的好处,那就是当某个接口的地址需要统一修改的时候,我们只需要对[代码]request.js[代码]进行修改,其他调用的地方都不需要动了。 错误信息的提炼 最后的最后,我们再补充一个可轻可重的点,那就是错误信息的提炼。 当我们在封装这么一个[代码]req[代码]对象的时候,我们的promise曾经reject过很多的错误信息,这些错误信息有可能来自: [代码]wx.request[代码]的fail; 不符合[代码]isHttpSuccess[代码]的网络错误; getSessionId失败; … 等等的一切可能。 这就导致了我们在提炼错误信息的时候陷入困境,到底catch到的会是哪种[代码]error[代码]对象? 这么看你可能不觉得有问题,我们来看看下面的例子: [代码]req.getHotList({ page: 1 }) .then((res) => { console.log(res); }) .catch((err) => { console.log(err); }); [代码] 假如上面的例子中,我想要的不仅仅是[代码]console.log(err)[代码],而是想将对应的错误信息弹窗出来,我应该怎么做? 我们只能将所有可能出现的错误都检查一遍: [代码]req.getHotList({ page: 1 }) .then((res) => { if (res.code !== 0) { // 后端接口报错格式 wx.showModal({ content: res.msg }); } }) .catch((err) => { let msg = '未知错误'; // 文本信息直接使用 if (typeof err === 'string') { msg = err; } // 小程序接口报错 if (err.errMsg) { msg = err.errMsg; } // 自定义接口的报错,比如网络错误 if (err.detail && err.detail.errMsg) { msg = err.detail.errMsg; } // 未知错误 wx.showModal({ content: msg }); }); [代码] 这就有点尴尬了,提炼错误信息的代码量都比业务还多几倍,而且还是每个接口调用都要写一遍~ 为了解决这个问题,我们需要封装一个方法来专门做提炼的工作: [代码]/** * 提炼错误信息 * 参数:err * 返回值:[string]errMsg */ function errPicker(err) { if (typeof err === 'string') { return err; } return err.msg || err.errMsg || (err.detail && err.detail.errMsg) || '未知错误'; } [代码] 那么过程会变成: [代码]req.getHotList({ page: 1 }) .then((res) => { console.log(res); }) .catch((err) => { const msg = req.errPicker(err); // 未知错误 wx.showModal({ content: msg }); }); [代码] 好吧,我们再偷懒一下,把wx.showModal也省去了: [代码]/** * 错误弹窗 */ function showErr(err) { const msg = errPicker(err); console.log(err); wx.showModal({ showCancel: false, content: msg }); } [代码] 最后就变成了: [代码]req.getHotList({ page: 1 }) .then((res) => { console.log(res); }) .catch(req.showErr); [代码] 至此,一个简单的wx.request封装过程便完成了,封装过的[代码]req[代码]比起原来,使用上更加方便,扩展性和可维护性也更好。 结尾 以上内容其实是简化版的[代码]mp-req[代码],介绍了[代码]mp-req[代码]这一工具的实现初衷以及思路,使用[代码]mp-req[代码]来管理接口会更加的便捷,同时[代码]mp-req[代码]也提供了更加丰富的功能,比如插件机制、接口的缓存,以及接口分类等,欢迎大家关注mp-req了解更多内容。 以上最终代码可以在这里获取:req.js。
2020-08-04 - 小程序开发中几个常见场景素材尺寸
本文背景在开发小程序的过程中,经常会遇到一些场景需要图片素材,这些素材尺寸如果当时要找起来,说实话,不是很容易,本文基于这个事实进行整理 本文内容具体的场景有 1)小程序logo 2)小程序底部导航图片 3)小程序分享图片尺寸 4)全屏背景图片 1)小程序头像的图片尺寸大小 144px*144px [图片] 占位 2)小程序菜单icon尺寸大小,81px*81px [图片]3) https://developers.weixin.qq.com/miniprogram/dev/reference/api/Page.html#onshareappmessageobject-object [图片] 4)关于第四个场景,具体看评论区留言吧。 本文总结本文主要汇总了小程序开发过程中常见的几个图片素材尺寸
2020-10-07 - 微信开发者工具设置 extraData编译后取不到了?
[图片]如图,编译场景 1037,extradata 设置后,在 onload 里调用wx.getEnterOptionsSync(),获取到的 extraData 为空对象
01-05 - 2024年了,webview缓存问题有解了吗?
如题,每次更新H5都要清除缓存太难受了
06-03 - web-view内嵌h5每次发包,缓存严重,加随机数也没用?有什么办法?
web-view src的html?加随机数 无法解决缓存问题 求助!!!急
2023-09-25 - 微信开发者工具使用调试器->Components Data查看组件的属性,出现异常
我的页面文件index有属性indexObj,组件文件有属性testObj 如图所示,我的<test>组件的属性,在Component Data中,应该显示为testObj[图片] 当我点击按钮运行一段setinterval的时候,组件显示的属性变成了页面的属性indexObj了。 [图片]
2023-06-08 - 开发者工具,调试器-Wxml-Component Data,多个组件时,面板数据不正确?
开发者工具稳定版:1.06.2402040 复现条件:一个Page中有多个组件,Wxml点击查看A组件,想查看A组件的Component Data。如果此时B组件一直在更新数据(如,更新进度条数据等),面板上显示的是B组件的Component Data。
04-01 - 线上版本部分机型 rich-text 重复渲染?
(出问题的机型:红米k50至尊版,苹果13) [图片][图片][图片]
06-17 - rich-text内容,只要有转义字符,就会渲染重复。
开发者工具,基础库版本,改为3.3.5,必复现。 华为p50pro真机也会复现,基础库版本也是3.3.5。
06-26 - rich-text渲染内容重复
开发者工具展示正常,真机中每段内容重复出现3次 [图片][图片] 接口返回数据如下, {"code":0,"msg":"Success","timestamp":1717035519366,"data":{"id":1004,"title":"教育部提示:严防4类陷阱","content":"<p style=\"margin-top:0px;margin-bottom:0px;padding:0px;font-family:;-webkit-tap-highlight-color:rgba(255, 255, 255, 0);list-style:inside none;border:0px;user-select:text;font-size:14px;line-height:2;color:#666666;letter-spacing:1px;white-space:normal;background-color:#F6F6F6;text-align:justify;text-size-adjust:none !important;\">\n\t<span style=\"font-size:14px;\">  当前,距毕业生离校不足2个月时间,正值高校毕业生求职关键期,一些不法分子打着招聘的幌子挖“坑”设陷,诈骗钱财、盗用信息、诱导犯罪等现象时有发生,严重损害毕业生就业权益。为保护自身安全和合法权益,高校毕业生在求职过程中,一定要增强三个意识,严防四类陷阱。</span>\n</p>\n<p style=\"margin-top:0px;margin-bottom:0px;padding:0px;font-family:;-webkit-tap-highlight-color:rgba(255, 255, 255, 0);list-style:inside none;border:0px;user-select:text;font-size:14px;line-height:2;color:#666666;letter-spacing:1px;white-space:normal;background-color:#F6F6F6;text-align:justify;text-size-adjust:none !important;\">\n\t<span style=\"font-size:14px;\">  筑牢防线增强三个意识</span>\n</p>\n<p style=\"margin-top:0px;margin-bottom:0px;padding:0px;font-family:;-webkit-tap-highlight-color:rgba(255, 255, 255, 0);list-style:inside none;border:0px;user-select:text;font-size:14px;line-height:2;color:#666666;letter-spacing:1px;white-space:normal;background-color:#F6F6F6;text-align:justify;text-size-adjust:none !important;\">\n\t<span style=\"font-size:14px;\">  一要增强风险防范意识。积极参加学校及相关部门组织的就业指导和安全教育活动,增强识别就业“陷阱”和违法违规行为的意识与能力,不走所谓的“求职捷径”,警惕潜在的“高薪骗局”。</span>\n</p>\n<p style=\"margin-top:0px;margin-bottom:0px;padding:0px;font-family:;-webkit-tap-highlight-color:rgba(255, 255, 255, 0);list-style:inside none;border:0px;user-select:text;font-size:14px;line-height:2;color:#666666;letter-spacing:1px;white-space:normal;background-color:#F6F6F6;text-align:justify;text-size-adjust:none !important;\">\n\t<span style=\"font-size:14px;\">  二要增强信息安全意识。通过国家大学生就业服务平台、高校就业网站等国家有关部门、地方和高校的校园招聘等正规途径获取就业信息,多渠道甄别,不盲目轻信;不随意打开陌生网址链接,谨慎对待索要敏感信息、扣留证明原件等行为。</span>\n</p>\n<p style=\"margin-top:0px;margin-bottom:0px;padding:0px;font-family:;-webkit-tap-highlight-color:rgba(255, 255, 255, 0);list-style:inside none;border:0px;user-select:text;font-size:14px;line-height:2;color:#666666;letter-spacing:1px;white-space:normal;background-color:#F6F6F6;text-align:justify;text-size-adjust:none !important;\">\n\t<span style=\"font-size:14px;\">  三要增强依法维权意识。主动了解学习求职就业有关法律知识,学会用法律维护自身权益。如在求职中本人合法权益遭受侵害,要积极收集并留存有关证据,及时向学校及有关部门求助,或向公安机关报案。</span>\n</p>\n<p style=\"margin-top:0px;margin-bottom:0px;padding:0px;font-family:;-webkit-tap-highlight-color:rgba(255, 255, 255, 0);list-style:inside none;border:0px;user-select:text;font-size:14px;line-height:2;color:#666666;letter-spacing:1px;white-space:normal;background-color:#F6F6F6;text-align:justify;text-size-adjust:none !important;\">\n\t<span style=\"font-size:14px;\">  提高警惕,严防四类陷阱</span>\n</p>\n<p style=\"margin-top:0px;margin-bottom:0px;padding:0px;font-family:;-webkit-tap-highlight-color:rgba(255, 255, 255, 0);list-style:inside none;border:0px;user-select:text;font-size:14px;line-height:2;color:#666666;letter-spacing:1px;white-space:normal;background-color:#F6F6F6;text-align:justify;text-size-adjust:none !important;\">\n\t<span style=\"font-size:14px;\">  一要严防非法职业中介陷阱。一些没有相关资质或冒用、伪造相关资质的“黑中介”,常打着介绍工作的幌子发布虚假招聘信息,以“轻松拿高薪”“升职加薪快”等为诱饵,使用各种手段骗取钱财。</span>\n</p>\n<p style=\"margin-top:0px;margin-bottom:0px;padding:0px;font-family:;-webkit-tap-highlight-color:rgba(255, 255, 255, 0);list-style:inside none;border:0px;user-select:text;font-size:14px;line-height:2;color:#666666;letter-spacing:1px;white-space:normal;background-color:#F6F6F6;text-align:justify;text-size-adjust:none !important;\">\n\t<span style=\"font-size:14px;\">  防范提示:高校毕业生通过中介服务机构求职,要选择诚信可靠、经营规范的服务机构,不要轻信口头承诺,一定要在确认相关内容的基础上签订正式服务协议。一旦遇到“黑中介”,应及时投诉举报,拒绝支付相关费用。</span>\n</p>\n<p style=\"margin-top:0px;margin-bottom:0px;padding:0px;font-family:;-webkit-tap-highlight-color:rgba(255, 255, 255, 0);list-style:inside none;border:0px;user-select:text;font-size:14px;line-height:2;color:#666666;letter-spacing:1px;white-space:normal;background-color:#F6F6F6;text-align:justify;text-size-adjust:none !important;\">\n\t<span style=\"font-size:14px;\">  二要严防招聘收费陷阱。不法分子常以招聘为名变相收取各类费用,牟取非法利益。有的以押金、保证金、办证费、服装费、资料费等名目收费,再以各种苛刻要求迫使求职者自动放弃求职或离岗,已交费用以各种理由不予退还。有的宣称具有知名公司内部推荐权,打着收费推荐优质岗位的幌子骗取钱财。有的与不良网贷平台勾结,利用毕业生初入职场、求职心切的特点,设置培训贷、购车贷、美容贷等新型招聘陷阱。有的以招聘为名变相招生,要求付费参加入职或考证培训,一旦收取费用便以各种理由拒绝履行承诺,甚至直接“卷款跑路”。</span>\n</p>\n<p style=\"margin-top:0px;margin-bottom:0px;padding:0px;font-family:;-webkit-tap-highlight-color:rgba(255, 255, 255, 0);list-style:inside none;border:0px;user-select:text;font-size:14px;line-height:2;color:#666666;letter-spacing:1px;white-space:normal;background-color:#F6F6F6;text-align:justify;text-size-adjust:none !important;\">\n\t<span style=\"font-size:14px;\">  防范提示:《劳动合同法》第九条规定:“用人单位招用劳动者,不得扣押劳动者的居民身份证和其他证件,不得要求劳动者提供担保或者以其他名义向劳动者收取财物。”若用人单位在招聘过程中以各种理由要求租用、购买各类工作设备或交钱、贷款才能够安排岗位的,应果断拒绝,以免上当受骗。对经付费培训可录用、包就业等要求,一定要警惕“挂羊头卖狗肉”陷阱,谨防既被坑骗钱财,又浪费时间精力。如交费一定要求出具正规发票并加盖单位公章,为可能发生的纠纷维权保留证据。</span>\n</p>\n<p style=\"margin-top:0px;margin-bottom:0px;padding:0px;font-family:;-webkit-tap-highlight-color:rgba(255, 255, 255, 0);list-style:inside none;border:0px;user-select:text;font-size:14px;line-height:2;color:#666666;letter-spacing:1px;white-space:normal;background-color:#F6F6F6;text-align:justify;text-size-adjust:none !important;\">\n\t<span style=\"font-size:14px;\">  三要严防招聘诈骗陷阱。不法分子常通过发布虚假招聘信息,诱导求职者从事、参与违法行为。有的在各类网络平台上发布事先编造的招工信息,以“高薪急聘”“学历不限”等字眼诱导求职者逐步暴露个人信息、下载刷单App,骗取求职者钱财。有的以“勤工俭学”“招聘兼职”“高额回报”等为诱饵,吸引求职者落入传销组织圈套。有的以招聘“行政秘书”“生活助理”为名,或打着招聘网络主播等新兴职业的幌子,要求女性求职者从事异性服务。有的以招聘名义,盗用求职者的银行卡、手机卡或支付账户等个人信息,用于诈骗、洗钱等违法活动。</span>\n</p>\n<p style=\"margin-top:0px;margin-bottom:0px;padding:0px;font-family:;-webkit-tap-highlight-color:rgba(255, 255, 255, 0);list-style:inside none;border:0px;user-select:text;font-size:14px;line-height:2;color:#666666;letter-spacing:1px;white-space:normal;background-color:#F6F6F6;text-align:justify;text-size-adjust:none !important;\">\n\t<span style=\"font-size:14px;\">  防范提示:高校毕业生要擦亮识别骗局的“慧眼”,掌握防范陷阱的“招数”,遇到“活少钱多”“轻松钱来”“躺平赚钱”等“听上去很美”的招聘信息和“天上掉馅饼”的“好事”,一定要提高警惕,多查多问多防备,谨防“踩雷”“掉坑”。</span>\n</p>\n<p style=\"margin-top:0px;margin-bottom:0px;padding:0px;font-family:;-webkit-tap-highlight-color:rgba(255, 255, 255, 0);list-style:inside none;border:0px;user-select:text;font-size:14px;line-height:2;color:#666666;letter-spacing:1px;white-space:normal;background-color:#F6F6F6;text-align:justify;text-size-adjust:none !important;\">\n\t<span style=\"font-size:14px;\">  四要严防“猫腻”合同陷阱。在合同签订过程中,个别用人单位为降低用人成本、规避用工责任而侵犯毕业生合法权益。有的仅签订《就业协议书》,或以谈话、电话等口头形式约定工作相关事项,没有签订书面劳动合同。有的合同内容简单,缺少工作岗位、工作地点、工资、劳动条件、合同期限等具体内容。有的以少缴税款为由,同时准备两份不同薪资的“阴阳合同”。有的包含“霸王条款”,要求几年内不得结婚、无条件服从加班、试用期离职不结算工资等。毕业生到岗工作后,特别是当出现一些争议时,就可能被用人单位以没有书面劳动合同或者违反合同相关条款为由,拖欠或拒发薪酬。</span>\n</p>\n<p style=\"margin-top:0px;margin-bottom:0px;padding:0px;font-family:;-webkit-tap-highlight-color:rgba(255, 255, 255, 0);list-style:inside none;border:0px;user-select:text;font-size:14px;line-height:2;color:#666666;letter-spacing:1px;white-space:normal;background-color:#F6F6F6;text-align:justify;text-size-adjust:none !important;\">\n\t<span style=\"font-size:14px;\">  防范提示:《劳动合同法》明确规定:建立劳动关系,应当订立书面劳动合同。高校毕业生在签订劳动合同前,应与用人单位认真协商、慎重对待,不可草率签订。签订合同时一定要仔细阅读,核实清楚是否具备《劳动合同法》规定的必备条款(用人单位基本情况、合同期限、工作内容和地点、工作时间和休息休假、劳动报酬、社会保险、劳动条件等),特别要高度警惕其中于法无据、明显不合理的条款,防止掉入陷阱,难以维权。若因故未能签订合同、订立协议,一旦遇到纠纷应及时寻求有关部门帮助,通过正规渠道予以妥善解决。</span>\n</p>","source":"信用中国","column":0,"status":1,"releaseTime":"2024-05-29","createBy":10409,"updateBy":10409,"updateTime":"2024-0-29 16:31:40","createTime":"2024-05-29 16:25:19","describe":"","orderNum":0,"isDelete":0,"area":"yx"}}
05-30 - 小程序一次性订阅消息详解
简介 相对来说小程序发送通知用得更多的还是一次性订阅模版,发现社区挺多同学对一次性订阅的一些细节设定存在不少疑问。所以这里整理了一些常见的问题。 订阅框长这样,本文也围绕这个弹窗展开: [图片] 常见问题Q&A 1.获取模版ID 1.1 如何获取到合适的模版ID? 答:进入MP后台,https://mp.weixin.qq.com, 可以在【功能】->【订阅消息】->【公共模板库】选择合适的模版。选择后在【我的模版】 查看到模版ID。 注意: 不同小程序,选用同一个模版,生成的模版ID是不一样的。 [图片] 1.2 如何申请新的模版? 答:在MP后台申请,入口比较隐蔽。如要在【公共模版库】搜索任意模版,然后翻到最后一页,会出现【帮助我们完善模板库】的选项,点击进入申请新模版。比如此处我搜索了签到 [图片] 2.订阅次数 2.1 勾选了【总是保持以上选择,不再询问】,是不是就可以多次向发送通知了? 答:不能,用户没有再次点击触发订阅的按钮就不会增加订阅次数。勾选之后只是触发订阅时不再弹窗,保持上一次用户的选项进行订阅接口的调用。 2.2 用户一天内多次点击订阅后,是不是就能发送多条通知? 答: 是的,用户一天内点了N次订阅,就可以向用户发送多条通知。 2.3 用户点击订阅后,此次发通知机会的有效期是多久? 答: 永久有效。 2.4 勾选部分模版,再选择勾选 【总是保持以上选择,不再询问】,点击【确定】后,下次订阅哪几个模版的订阅次数会增加? [图片] 答: 如上图,只勾选了AB,然后保持选项点击【确定】,下次订阅时只有A,B模版的订阅次数会增加。 2.5 勾选部分模版,再选择勾选 【总是保持以上选择,不再询问】,点击【取消】后,下次订阅哪几个模版的订阅次数会增加? 答: 如果选择了【取消】+ 【保持选项】,所有订阅消息次数都不会再增加。如上图,不管是否勾选,A、B、C三个模版次数都不会增加。 2.6 勾选【总是保持以上选择,不再询问】选项后,如何修改选择? 答: 可以在小程序设置页面,配置是否接收模版消息。(小程序右上角三点按钮,可以唤起进入设置页面的面板) [图片] 2.7 为什么我设置的通知页面没有显示MP后台配置的通知模版? 答:只有勾选过【总是保持以上选择,不再询问】的模版消息才会进入这个配置页面。 2.8 关闭接口通知按钮后(上图红框内按钮),再开启,订阅次数怎么计算? 答: 关闭按钮后,所有通知都无法接收,订阅次数全部清零。所以重新开启后,也需要用户重新订阅才能再次发送通知。 3.弹窗相关 3.1 模版ABC已经勾选【保持选项】,在另一处同时订阅ADF,此时还会弹窗吗? 答: 会,但是弹窗中只会有两个模版DF,模版A不显示。 3.2 开发者勾选【总是保持以上选择,不再询问】后,怎么重新唤起弹窗? 答:微信开发者工具,清除全部缓存。重新生成二维码,测试机扫码后即可重新唤起弹窗。 Tips:登陆开发者工具的微信账号和需要重置弹窗的微信账号需要保持一致。
09-04 - 针对新手很容易出现理解误区的微信小程序订阅消息模块
1. 写在前面 微信小程序下架了模板消息功能,取而代之的是订阅消息功能。这个订阅消息目前又分为「一次性订阅」和「永久订阅」。使用订阅消息也有一段时间了,感觉对新手订阅消息很容易让新开发者进入一个理解的误区,这里觉得有必要说出来 2. 理解误区 很多新手认为,只要用户勾选了小程序端订阅消息弹出时底部的「总是保持以上选择…」后,就可以「为所欲为」的不限次数的推送订阅消息给用户了。如下图: [图片] 3. 正确理解 如果你使用的「一次性订阅」模板(目前发现绝大多数开发者都是只能用一次性的,因为永久性的订阅消息申请门槛太高),那么勾选底部的「总是…」这个并不代表以后可以直接推送了。官方原话wx.requestSubscribeMessage的介绍里是这样写的: 3.1 官方说明 wx.requestSubscribeMessage(Object object) 基础库 2.8.2 开始支持,低版本需做兼容处理。 调起客户端小程序订阅消息界面,返回用户订阅消息的操作结果。当用户勾选了订阅面板中的“总是保持以上选择,不再询问”时,模板消息会被添加到用户的小程序设置页,通过 wx.getSetting 接口可获取用户对相关模板消息的订阅状态。 注意事项 一次性模板 id 和永久模板 id 不可同时使用。 低版本基础库2.4.4~2.8.3 已支持订阅消息接口调用,仅支持传入一个一次性 tmplId / 永久 tmplId。 2.8.2 版本开始,用户发生点击行为或者发起支付回调后,才可以调起订阅消息界面。 2.10.0 版本开始,开发版和体验版小程序将禁止使用模板消息 fomrId。 3.2 重点关注 这里重点关注第7条:「用户发生点击行为或者发起支付回调后,才可以调起订阅消息界面。」这就意味着你需要在用户主动点击某个组件是触发调用wx.requestSubscribeMessage方法再次订阅,订阅后,你才可以「为所欲为」推送一次模板消息,注意只能一次。下次再想推送时,需要用户再次点击触发wx.requestSubscribeMessage。 4. 破局方案 目前订阅消息功能,就是这么个情况,所以针对这个情况的替代方案有以下 4.1 永久性订阅消息 如果能达到申请「永久性订阅」消息的模板的门槛,那自然是极好的,直接用永久性模板「为所欲为」。 4.2 使用服务号的模板消息替代 比较常用的是使用公众号服务号的模板消息代替小程序的订阅消息功能,公众号的模板消息功能限制就比订阅号好多了,基本上可以「为所欲为」的推送。但是这个方案有个致命的运营成本:必须要用户关注公众号,还有小程序要跟公众号同一主体并绑定在开放平台下。同时开发成本有所增加,要采用unionId机制来打通小程序跟公众号的openId。这个具体的实现方案,大家有兴趣的话可以讨论下。笔者目前就是用这种方案的。 5. 几个注意点 5.1 官方提示 订阅消息如果选择选择‘总是保持以上选择,"不再询问"后的设置问题: 目前是选择‘总是保持以上选择,"不再询问"后,可以在设置中开启或拒绝接收,但不会再次拉起授权弹窗 6. 长期性订阅消息 请参考官方最新文档: 小程序模板消息能力调整通知 | 微信开放社区 https://developers.weixin.qq.com/community/develop/doc/00008a8a7d8310b6bf4975b635a401 长期性订阅消息 一次性订阅消息可满足小程序的大部分服务场景需求,但线下公共服务领域存在一次性订阅无法满足的场景,如航班延误,需根据航班实时动态来多次发送消息提醒。为便于服务,我们提供了长期性订阅消息,用户订阅一次后,开发者可长期下发多条消息。 目前长期性订阅消息仅向政务民生、医疗、交通、金融、教育等线下公共服务开放,后期将逐步支持到其他线下公共服务业务。 7.题外话 鉴于被戴上各种「刷赞,冲级,让社区点赞“通货膨胀”」等等一些恶毒字眼(最近多了个职业回复的「雅称」),各种帽子戴得,做一个开发爱好者积极分享和解决各种问题太难了,姑且不论咱写一篇文章需要截图多少,单单排版就得废掉俺多少时间哈,很受伤,所以本人决定在微信开放者社区封笔。你看到是俺最后一篇发表在微信开放社区的文章。如果你想继续查看俺的一些文章可以私聊我。我会在其他平台保持继续创作。bye-bye~ 8. 最最重要的来了 看完后觉得有用记得点赞~~ ↓点赞处↓
2020-09-04 - 公众号模板消息也分一次性订阅和长期订阅模板吗?
小程序消息推送模板分一次性订阅和长期订阅。那公众号的模板消息也分吗?
05-11 - 小程序一次性订阅消息为什么有的时候可以发送多条,有的时候只能发送一条?
[图片][图片]
2022-12-01 - unable to verify the first certificate?
已经勾选了不校验安全域名、TLS 版本以及 HTTPS 证书,上传的时候报错uploadFile:fail Error: unable to verify the first certificate
2019-11-27 - Error: unable to verify the first certificate?
[图片][图片] windows 10 稳定版 Stable Build (1.03.2006090) 针对微信小程序开发者工具以上情况,望官方收悉审核并解答,感谢。
2020-08-10 - 直接分享直播间出去,用户点击获取不到自定义的custom_params参数?
如题: [图片] 通过上面的入口直接分享出去,用户点击进直播间,这时候用户去点击商品,进入商品详情页,商品详情页这边就没法获得custom_params参数,怎么整?
2020-03-17 - 【小程序直播】通过分享的方式进入直播间,如何修改自定义参数custom_params?
目前在app.onShow可以获取到custom_params这个参数,但是如何修改呢? 目前有需要修改的场景:用户A在小程序里跳转进入直播间,custom_params携带了用户A的信息,用户A分享给用户B,用户B点击分享卡片进入直播间,此时需要将custom_params变更为用户B的信息,实现用户B分享出去的卡片携带自己的信息,目前没修改携带出去还是A的信息,或者能否有别的思路呢?
2021-07-19 - 【小程序直播】通过用户A分享的方式进入直播间,如何修改用户B的自定义参数custom_params?
用户A在小程序里跳转进入直播间,custom_params携带了用户A的信息,用户A分享给用户B,用户B点击分享卡片进入直播间,此时需要将custom_params变更为用户B的信息,实现用户B分享出去的卡片携带自己的信息,目前没修改携带出去还是A的信息,或者能否有别的思路呢?
2023-04-25 - 关于直播插件分享,用户订阅过后,下次通过开播提醒进入,不能获取到custom_params参数?
通过直播间分享给用户代了custom_params参数, 用户点击分享链接进入直播间,订阅直播。 用户通过服务器消息的开通提醒链接进入直播间,未获取到之前分享的coustom_params参数 3月17号我看有人提交了这个问题,说要解决,今天测试还是有这个问题, 这个问题有解决吗,具体版本是多少
2020-03-31 - 请问当一个用户点链接进入分享出去的直播间时,如何拿到openid?
微信直播的研发人员您们好,我司小程序有幸得到了测试资格,这几天写了几个demo,发现有一个问题无法解决,所以想来请教下。 当使用live-player-plugin组件时,用户在直播间可以直接点右上角的分享把这个直播间分享出去。我用复制页面路径功能查看到这个分享出去的直播间链接里是带了分享人的openid的。形式大概是: __plugin__/wx2b03c6e691cd7370/pages/live-player-plugin.html?room_id=9&type=1&openid=***&close_picture_in_picture_mode=false 但是当有人通过这个链接直接进入直播间时,我没办法拿到这个openid。理论上这个参数该在对应page的onLoad里拿,但是页面是你们插件内部的,App里也没有办法去hook其他page的onLoad。我尝试在App.onShow里查看query,是没有参数的,所以我不知道该如何取这个openid。我也查看了开发文档,目前并没有暴露取这个的接口。 另外我注意到在新版里,点击商品链接会带上room_id,这是一个很好的改动,让商品能和主播建立联系。但是在很多场景里,我们同样也希望分享者和主播和商品都建立联系,我想你们在分享链接里带上openid也是出于这个考虑。可是开发者却取不到这个openid。 所以我想问问: 1 是不是有获取这个openid的接口和方法只是我不知道,请指点一下谢谢。 2 如果没有,能不能提供一个这样的功能,或者在点击商品链接时把这个直播间的分享者的openid也带上。 3 如果出于openid的敏感性考虑不提供这样的功能,能不能提供一个可以在后台换取用户身份的类似的token? 4 如果以上说的都不行,微信直播这个组件从一开始设计就是不希望开发者取到分享直播间的人的信息,能不能说明一下,这对我司接下来的业务模式有较大影响,如果不行我们就早点死心寻找其他做法。 字打的有点多,感谢耐心看完,望早日回复。
2020-02-25 - 小程序直播间分享传参以及获取,海报为什么不行呢
直接上代码 [图片] 获取场景一:当通过直播间右上角或者左下角分享小程序卡片,其他人进入直播间时,访问商品详情页面会携带对应参数,通过直播组件返回到livePlayer.getShareParams()里面(已测ok) [图片] 场景二:他人通过小程序卡片,访问直播间,点击左上角返回首页时,在onload里面携带参数,则需要通过反编译获取参数(已测ok) [图片] 场景三:直播间分享生成海报,要如何获取自定义参数,以上方式无效,请知道的小伙伴告知!!!
2020-12-31 - 小程序直播 主播端分享直播间卡片 能不能携带自定义参数?
在线等
2020-06-02 - 引用小程序直播组件内,右上角的分享能不能带参数,或者把分享按钮隐藏掉?
rt,我们一般会在分享的地方带上参数来统计被访问信息,最近在研究小程序直播组件,右上角的分享能添加自定义参数吗,如果不能加参数的话,那能否隐藏掉避免用户从这里分享呢?
2020-03-20 - 小程序直播生成带自定义参数的房间分享码,如何获取这些参数?
小程序直播生成带自定义参数的房间分享码,通过getShareParams无法取到这些参数,如何获取这些参数?分享卡片的方式没有问题,通过getShareParams可以获取参数。
2020-04-25 - 小程序webview的网页用了wx-open-launch-weapp标签可以跳转第三方小程序吗?
webview嵌套网页标签使用wx-open-launch-weapp,可以跳转当前的小程序路径,第三方小程序路径点击无反应。这种情况是不支持吗
2023-07-10 - web-view内公众号文章跳转回小程序,报当前小程序无法打开第J站小程序?
小程序里用web-view组件展示关联的公众号文章,公众号文章里有小程序卡片,还是链接的本小程序,现在在开发版和体验版是都无法从公众号文章里实现跳转到小程序,点击会弹出对话框“当前小程序无法打开第J站小程序”,因为这个问题,没有做公开版。我想问,如果做了公开版会不会就可以实现跳转了? 七月份做过一个demo,在开发版里是可以实现跳转的,只不过是跳转到公开版的小程序,现在再用原来的demo测试,也是报错,很疑惑,是官方做了什么调整吗?
2019-08-30 - 微信公众号网页JS-SDK使用wx.launchMiniProgram跳转小程序,提示没有权限?
在进行微信公众号网页开发时,有一个要跳转到微信小程序的功能,我看微信的JS-SDK里存在launchMiniProgram这个功能:[图片]我就想用这个API来实现,我在wx.config里的jsApiList也写了这个API名字[图片], 但是在运行时提示launchMiniProgram没有权限:[图片], 配置里写的另外两个API都有权限:[图片],我想问一下launchMiniProgram这个API是有什么使用条件吗?还是说只能用开放标签来实现跳转?
2022-08-13 - web-view 内嵌H5能跳转第三方小程序吗
web-view 内嵌H5能跳转第三方小程序吗
2023-02-01 - H5网页跳转小程序
现在小程序越来越普遍了,从H5网页(要在微信浏览器下打开的)跳转到相应小程序的场景也越来越多。至此微信提供了相应的微信开放标签让网页开发者可安全便捷地使用微信或系统的能力,为微信用户提供更优质的网页体验。 需要注意的是,微信开放标签有最低的微信版本和最低的系统版本要求。 微信版本要求为:7.0.12及以上系统版本要求为:iOS 10.3及以上、Android 5.0及以上 对于符合微信或系统最低版本要求但仍无法使用微信开放标签的场景,将会在下方使用步骤中的[代码]wx.config[代码]权限验证成功后触发[代码]WeixinOpenTagsError[代码]事件告知开发者。仅无法使用微信开发标签,JS-SDK其他功能不受影响。可通过如下方法监听并进行回退兼容: document.addEventListener('WeixinOpenTagsError', function (e) { console.error(e.detail.errMsg); // 无法使用开放标签的错误原因,需回退兼容。仅无法使用开放标签,JS-SDK其他功能不受影响 }); 根据目前已知的错误场景,回退兼容建议如下: iOS15底层 WebKit 接口发生变更,微信版本8.0.8以下(不包括8.0.8)无法使用开放标签,可引导用户升级最新版本微信;开放标签依赖Web Components方案,极少部分 Android 系统可能由于版本太低而不支持,可引导用户升级系统固件。H5网页跳转小程序有如下步骤: 1.在微信公众号(已认证的服务号)绑定“JS接口安全域名” 如果是公众号身份的网页,需要绑定安全域名。登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。 如果是使用小程序云开发静态网站托管的小程序网页,则不需绑定安全域名即可直接使用(即跳过该"步骤一:绑定JS接口安全域名")。 2.引入JS文件 在需要调用 JS 接口的页面引入如下 JS 文件:http://res.wx.qq.com/open/js/jweixin-1.6.0.js (支持https) 如需进一步提升服务稳定性,当上述资源不可访问时,可改访问:http://res2.wx.qq.com/open/js/jweixin-1.6.0.js (支持https) 备注:支持使用 AMD/CMD 标准模块加载方法加载。 注意:js文件必须使用1.6.0版本以上 3.通过config接口注入权限验证配置并申请所需开放标签 与使用 JS-SDK 配置方式相同,所有需要使用开放标签的页面必须先注入配置信息,并通过[代码]openTagList[代码]字段申请所需要的开放标签,否则将无法使用(同一个 url 仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用。目前Android微信客户端不支持pushState的H5新特性,所以使用pushState来实现web app的页面会导致签名失败,此问题会在Android6.2中修复)。开放标签的申请和 JS 接口的申请相互独立,因此是可以同时申请的。 wx.config({ debug: true, // 开启调试模式,调用的所有 api 的返回值会在客户端 alert 出来,若要查看传入的参数,可以在 pc 端打开,参数信息会通过 log 打出,仅在 pc 端时才会打印 appId: '', // 必填,公众号的唯一标识 timestamp: , // 必填,生成签名的时间戳 nonceStr: '', // 必填,生成签名的随机串 signature: '',// 必填,签名 jsApiList: [], // 必填,需要使用的 JS 接口列表 openTagList: [] // 可选,需要使用的开放标签列表,例如['wx-open-launch-app'] }); 注意:如果使用的是小程序云开发静态网站托管的域名的网页,可以免鉴权直接跳任意合法合规小程序,调用 wx.config 时 appId 需填入非个人主体的已认证小程序,不需计算签名,timestamp、nonceStr、signature 填入非空任意值即可。 4.通过ready接口处理成功验证 wx.ready(function () { // config信息验证后会执行 ready 方法,所有接口调用都必须在 config 接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在 ready 函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在 ready 函数中 }); 5.通过error接口处理失败验证 wx.error(function (res) { // config信息验证失败会执行 error 函数,如签名过期导致验证失败,具体错误信息可以打开 config 的debug模式查看,也可以在返回的 res 参数中查看,对于 SPA 可以在这里更新签名 }); 接口调用说明所有接口通过wx对象(也可使用jWeixin对象)来调用,参数是一个对象,除了每个接口本身需要传的参数之外,还有以下通用参数: success:接口调用成功时执行的回调函数。fail:接口调用失败时执行的回调函数。complete:接口调用完成时执行的回调函数,无论成功或失败都会执行。cancel:用户点击取消时的回调函数,仅部分有用户取消操作的api才会用到。trigger: 监听Menu中的按钮点击时触发的方法,该方法仅支持Menu中的相关接口。备注:不要尝试在trigger中使用ajax异步请求修改本次分享的内容,因为客户端分享操作是一个同步操作,这时候使用ajax的回包会还没有返回。 以上几个函数都带有一个参数,类型为对象,其中除了每个接口本身返回的数据之外,还有一个通用属性errMsg,其值格式如下: 调用成功时:"xxx:ok" ,其中xxx为调用的接口名 用户取消时:"xxx:cancel",其中xxx为调用的接口名 调用失败时:其值为具体错误信息 使用说明 所使用的标签允许提供插槽,由于插槽中模版的样式是和页面隔离的,因此需要注意在插槽中定义模版的样式。插槽模版及样式均需要通过[代码]<script type="text/wxtag-template"></script>或<template></template>[代码]进行包裹。另外,对于具名插槽还需要通过[代码]slot[代码]属性声明插槽名称,下文标签插槽中的 default 插槽为默认插槽,可不声明插槽名称。 对于标签事件,均可通过[代码]event.detail[代码]获得详细信息。如果无特殊说明,下文标签事件说明中的返回值均指代[代码]event.detail[代码]中的内容。 另外,需要注意以下几点: 页面中与布局和定位相关的样式,如[代码]position: fixed; top -100;[代码]等,尽量不要写在插槽模版的节点中,请声明在标签或其父节点上;对于有 CSP 要求的页面,需要添加白名单[代码]frame-src https://*.qq.com webcompt:[代码],才能在页面中正常使用开放标签。(CSP相关内容可查看以下几篇文章:https://zhuanlan.zhihu.com/p/142987601、https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy)开放对象已认证的服务号,服务号绑定“JS接口安全域名”下的网页可使用此标签跳转任意合法合规的小程序。已认证的非个人主体的小程序,使用小程序云开发的静态网站托管绑定的域名下的网页,可以使用此标签跳转任意合法合规的小程序。代码 参考:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/guide/staticstorage/jump-miniprogram.html https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_Open_Tag.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>H5跳转小程序</title> <!-- weui 样式 --> <link rel="stylesheet" href="https://res.wx.qq.com/open/libs/weui/2.4.1/weui.min.css"> <!-- 页面样式 start --> <style> /* --------START reset.css------- */ * { margin: 0; padding: 0; } html, body { background-color: #fff; } a { text-decoration: none; } a, button, input, span, div { -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } li { list-style-type: none; } /* --------END reset.css------- */ .hidden { display: none; } .full { position: absolute; top: 0; bottom: 0; left: 0; right: 0; } .public-web-container, .wechat-web-container, .wechat-web-container wx-open-launch-weapp, .desktop-web-container { display: flex; flex-direction: column; align-items: center; } .public-web-container p, .wechat-web-container p, .desktop-web-container p { position: absolute; top: 40%; } .public-web-container a { position: absolute; bottom: 40%; } .wechat-web-container wx-open-launch-weapp { position: absolute; bottom: 40%; left: 0; right: 0; } .wechat-web-container .open-btn { display: block; margin: 0 auto; padding: 8px 24px; width: 200px; height: 45px; border: none; border-radius: 4px; background-color: #07c160; color: #fff; font-size: 18px; text-align: center; } </style> <!-- 页面样式 end --> </head> <body> <!-- 页面容器 start --> <div id="h5OpenMiniprogram"> <!-- <template> --> <!-- 页面内容 start --> <div class="page full"> <!-- 移动端微信外部浏览器 --> <div id="public-web-container" class="hidden"> <p>正在打开“小程序名字”</p> <a href="javascript:" id="public-web-jump-button" 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>点击以下按钮打开“小程序名字”</p> <!-- username:必填,所需跳转的小程序原始id,即小程序对应的以gh_开头的id; path:非必填,所需跳转的小程序内页面路径及参数(默认小程序的初始页面【即首页】) --> <wx-open-launch-weapp id="launch-btn" username="gh_XXX" path="/pages/XXX"> <!-- 第一种: 不适用于Vue.js开发的项目,template标签会冲突 --> <template> <style> .open-btn { display: block; margin: 0 auto; padding: 8px 24px; width: 200px; height: 45px; border: none; border-radius: 4px; background-color: #07c160; color: #fff; font-size: 18px; text-align: center; } </style> <button class="open-btn">打开小程序</button> </template> <!-- 第二种:几乎适用于所有前端框架开发的项目 --> <!-- <script type="text/wxtag-template"> <style> .open-btn { display: block; margin: 0 auto; padding: 8px 24px; width: 200px; height: 45px; border: none; border-radius: 4px; background-color: #07c160; color: #fff; font-size: 18px; text-align: center; } </style> <button class="open-btn">打开小程序</button> </script> --> </wx-open-launch-weapp> </div> <!-- 桌面端 --> <div id="desktop-web-container" class="hidden"> <p>请在手机打开网页链接</p> </div> </div> <!-- 页面内容 end --> <!-- </template> --> </div> <!-- 页面容器 end --> <!-- 引入jQuery --> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script> <!-- 调试用的移动端 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) { document.addEventListener('WeixinOpenTagsError', function (e) { console.error(e.detail.errMsg); // 无法使用开放标签的错误原因,需回退兼容。仅无法使用开放标签,JS-SDK其他功能不受影响 }); if (document.readyState === "complete" || document.readyState === "interactive") { fn(); } else { document.addEventListener("DOMContentLoaded", fn); } } docReady(async function () { var ua = navigator.userAgent.toLowerCase(); var isWXWork = ua.match(/wxwork/i) == "wxwork"; var isWeixin = !isWXWork && ua.match(/micromessenger/i) == "micromessenger"; console.log("isWeixin", isWeixin, isWXWork); var isMobile = false; var isDesktop = false; if (navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|IEMobile)/i)) { isMobile = true; } else { isDesktop = true; } if (isWeixin) { var containerEl = document.getElementById("wechat-web-container"); containerEl.classList.remove("hidden"); containerEl.classList.add("full", "wechat-web-container"); // 公众号网页需要绑定安全域名 // 获取签名,timestamp、nonceStr、signature $.ajax({ url: "请求地址", dataType: "json", success: function (res) { console.log("WeChatConfig", res); if (res.id === 1) { var data = res.items; // 根据实际情况返还的数据进行赋值 wx.config({ // debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印 appId: data.appId, // 必填,公众号的唯一标识 timestamp: data.timestamp, // 必填,生成签名的时间戳 nonceStr: data.nonceStr, // 必填,生成签名的随机串 signature: data.signature, // 必填,签名 jsApiList: ["chooseImage"], // 必填,需要使用的JS接口列表(此处随意一个接口即可) openTagList: ["wx-open-launch-weapp"], // 可选,需要使用的开放标签列表,例如['wx-open-launch-app'] }); /** * config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后。 * config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。 * 对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中 * */ wx.ready(function (res2) { console.log("ready", res2); var launchBtn = document.getElementById("launch-btn"); launchBtn.addEventListener("ready", function (e) { console.log("开放标签 ready"); }); launchBtn.addEventListener("launch", function (e) { console.log("开放标签 success"); }); launchBtn.addEventListener("error", function (e) { console.log("开放标签 fail", e.detail); }); }); // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名 wx.error(function (err) { console.log("error", err); }); } } }) // 小程序云开发静态网站托管的网页 // var launchBtn = document.getElementById("launch-btn"); // launchBtn.addEventListener("ready", function (e) { // console.log("开放标签 ready"); // }); // launchBtn.addEventListener("launch", function (e) { // console.log("开放标签 success"); // }); // launchBtn.addEventListener("error", function (e) { // console.log("开放标签 fail", e.detail); // }); // wx.config({ // // debug: true, // 调试时可开启 // appId: "", // 非个人主体的已认证的小程序APPID // 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, // 必填,表示是未登录模式 // resourceAppid: "小程序 AppID", // 资源方 AppID // resourceEnv: '云开发环境 ID', // 资源方环境 ID // }); // 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_loadin"); // buttonLoadingEl.classList.add("hidden"); // }) // } catch (error) { // buttonEl.classList.remove("weui-btn_loadin"); // buttonLoadingEl.classList.add("hidden"); // throw error; // } } }); async function openWeapp(onBeforeJump) { console.log("未开通云开发环境", onBeforeJump); // 因未开通云开发环境,此处不做处理 // var c = window.c; // const res = await c.callFunction({ // name: "public", // data: { // action: "getUrlScheme", // }, // }); // console.warn(res); // if (onBeforeJump) { // onBeforeJump(); // } // location.href = res.result.openlink; } </script> </body> </html> 错误提示 (1)没有在“JS接口安全域名”设置 [图片] 成功提示 (1)微信开发者工具 [图片] (2)真机:会有要打开小程序的名字 [图片]
03-06 - web-view内嵌h5中使用wx.miniProgram.navigateTo跳转其他小程序无效?
wx.miniProgram.getEnv(res => { if (res.miniprogram) { wx.miniProgram.navigateTo({ url: '/pages/index/index?appid=xxx', success: (result) => { console.log(mpUrl, 888888) console.log(result) alert(JSON.stringify(result)); // 此处会打印出;{"errMsg":"invokeMiniProgramAPI:ok"} console.log("打开小程序成功!!"); }, fail: (err) => { this.$toast(`打开失败${err}`) wx.navigateBack(); }, complete: () => {} }); } else { this.$toast("请在小程序环境打开"); } })
2022-05-30