今天发现在开发新项目时,微信分享失效了,开启 debug = true 后,在微信开发工具中提示:
{"errMsg":"updateTimelineShareData:fail, the permission value is offline verifying"}
在真机上提示:
{"errMsg":"config:ok"}
{"errMsg":"updateAppMessageShareData:ok"}
{"errMsg":"updateTimelineShareData"}
仍然找不出原因。
尝试打开已上线的项目,分享功能均正常。
偶然发现,当打开使用 JS-SDK 分享后的图文框的页面,能够正常分享,而直接点开链接的页面,没有分享按钮。
这难免不让人联想到最近GJ出的新政,新版微信已经开放淘宝、抖音等平台的链接打开权限,只是当点击链接的时候会出现一个风险提示页面:
而一旦由这个页面进入的网页,分享功能均不能正常。
另外还测试了以下几种情况的分享功能也能正常:
公众号推送的图文或链接、公众号菜单、个人发送到公众号的链接、通过扫一扫打开的页面等。
-- 2021.9
ASP.NET Web API 返回 Unauthorized 401 未授权代码:
return Unauthorized(new AuthenticationHeaderValue("getUserInfo"));
响应的头部信息是这样的:
以微信小程序中获取 header 的 www-authenticate 为例,不同操作系统中获取的 key 是不一样的:
iOS:
Android:
微信开发者工具:
所以,小程序端获取该值,暂时使用以下代码吧:
let www_authenticate;
if (!www_authenticate) {
www_authenticate = res.header['Www-Authenticate']; // iOS
}
if (!www_authenticate) {
www_authenticate = res.header['WWW-Authenticate']; // Android / 微信开发者工具
}
if (!www_authenticate) {
www_authenticate = res.header['www-authenticate']; // ASP.NET Web API 原始输出
}
if (!www_authenticate) {
www_authenticate = res.header['WWW-AUTHENTICATE']; // 其它情况
}
二维码类型 | 可扫码授权的微信号 | 其它微信号 | ||
直接扫码 | 将二维码截图发送给可扫码授权的微信号 | 无需劳烦管理员的方式 | ||
登录微信公众平台 | 管理员与运营者 | 扫码后需管理员验证登录(管理员通过“公众平台安全助手”接收消息,点开详情后点击“确定”) | 授权人用摄像头扫码①,点击“确定” | 成为运营者② |
设置公众号IP白名单 | 管理员与长期运营者 | 无法完成 | 授权人用摄像头扫码①,点击“确定” | 成为长期运营者② |
公众号绑定运营者 | 管理员 | 无法完成 | 管理员用摄像头扫码①,点击“确定” | 无 |
小程序添加/删除项目成员 | 管理员 | 无法完成 | 管理员直接识别二维码,点击“确定” | 无 |
小程序修改名称、修改简称、修改登录邮箱、修改密码 | 管理员 | 无法完成 | “修改简称”管理员用摄像头扫码①,点击“确定”,其它未测 | 无 |
小程序修改业务域名 | 管理员、有“开发者”权限的项目成员 | 无法完成 | 授权人直接识别二维码,点击“确定” | 成为有“开发者”权限的项目成员 |
微信开放平台绑定小程序 | 管理员 | 无法完成 | 管理员用摄像头扫码①,点击“确定” | 无 |
① 摄像头扫码:无法直接用“识别二维码”,必须把二维码发送到身边的其它设备,再使用手机摄像头完成扫码。
② 成为运营者要求绑定银行卡;成为运营者将占用“微信号绑定的帐号”数量,详见说明。若达到上限,只有法定代表人可继续成为运营者。在公众号“公众平台安全助手”中可查询绑定的帐号。
另外:
小程序添加/删除体验成员无须管理员授权
如果管理员未关注公众号“公众平台安全助手”,待测……
Dark Mode 亦称为 暗黑模式、黑暗模式、暗色模式、黑夜模式、深夜模式、夜间模式 等,以下介绍几种常用软件的 Dark Mode 的设置方法。
iOS:
【iOS 13+】在 设置 - 显示与亮度 - 选择“深色”
【iOS 11+】在 设置 - 通用 - 辅助功能 - 显示调节 - 反转颜色 中开启“智能反转”。
“智能反转”缺点:第三方应用上显示的图片会以“经典反转”的方式展示。
Android:
设置 - 显示 - 主题模式,选择“暗色主题”
版本支持:Android 9.0 - Pie(Android P)
macOS:
系统偏好设置 - 通用 - 外观,低版本系统中勾选“使用暗色菜单栏和 Dock”,高版本系统中直接点击预览图选择主题。
版本支持:在 OS X Yosemite 10.10 中提供支持,在 macOS Mojave 10.14 中全新升级。
Windows:
桌面右键“个性化”(或从 Windows 设置中打开),在“颜色”选项卡,选择默认应用模式“暗”。
版本支持:Windows 10 October 2018 Update(版本 1809)
Microsoft Office:
文件 - 选项 - 常规 - Office 主题:黑色
在一个组件中设置后(如 Word),会在其它的组件中同时生效(如 Excel)。但 Visio 没有“黑色”主题(至少在 2019 中),我尝试更改为“深灰色”,Word 也变为“深灰色”,然后在未关闭 Visio 的情况下再次更改 Word 为“黑色”,Visio 界面竟然也变成了“黑色”,设置选项中为空白。
版本支持:Office 2016
Adobe Photoshop:
点开 菜单:编辑 - 首选项 - 界面,根据自已喜爱更改颜色方案。
版本支持:Photoshop CS6(可能更早),新版中已默认启用
CorelDRAW:
点开菜单:工具 - 选项,左侧展开 工作区 - 外观,主题选择“暗”或“黑体”。
版本支持:CorelDRAW X8(可能更早)
Microsoft Visual Studio:
点开菜单:工具 - 选项 即可更改颜色主题为“深色”(左侧选项卡为 环境-常规)。
版本支持:Visual Studio 2012
微信开发者工具:
点开菜单:设置 - 外观设置,选择“深色主题”
仅在文件代码面板有效
Microsoft Edge:
设置 - 自定义 - 选择一个模式 - 暗
Chrome:
在 Chrome 74 版本中支持。
其开发者工具(F12)早在 50 版本中已提供 Dark 主题,在开发者工具右上角展开竖状三点图标 - Settings - Theme: Dark
Windows 的 Chrome 的 Dark 模式无需设置,会根据 Windows 自身是否为暗模式来调整。
因其 Dark 模式不容易区分当前标签页,如需禁用 Dark 模式,参此文
Adobe Acrobat Reader DC:
点开菜单:视图 - 显示主题 - 深灰
HBuilder X:
点开菜单:工具 - 主题 - 酷黑
Code Write:
设置 - Editor - Theme - Dark(默认已启用)
本文不定时更新中……
收集了一些在开发过程中遇到的一些问题的解决方法,适合新手。
异常:
出现脚本错误或者未正确调用 Page()
原因:不小心删了第一行内容:<template>
异常:
模块编译失败:TypeError: Cannot read property 'for' of undefined
at fixDefaultIterator (D:\HBuilderX\plugins\uniapp\lib\mpvue-template-compiler\build.js:4277:24)
at mark (D:\HBuilderX\plugins\uniapp\lib\mpvue-template-compiler\build.js:4306:5)
at markComponent (D:\HBuilderX\plugins\uniapp\lib\mpvue-template-compiler\build.js:4371:5)
at baseCompile (D:\HBuilderX\plugins\uniapp\lib\mpvue-template-compiler\build.js:4384:15)
at compile (D:\HBuilderX\plugins\uniapp\lib\mpvue-template-compiler\build.js:4089:28)
at Object.module.exports (D:\HBuilderX\plugins\uniapp\lib\mpvue-loader\lib\template-compiler\index.js:43:18)
原因:新建的页面(简单模板)只有以下 3 个标签,须在 <template /> 中添加一些代码,如 <view />
<template>
</template>
<script>
</script>
<style>
</style>
异常:
模块编译失败:TypeError: Cannot read property 'toString' of undefined
at Object.preprocess (D:\HBuilderX\plugins\uniapp\lib\preprocess\lib\preprocess.js:56:15)
at Object.module.exports (D:\HBuilderX\plugins\uniapp\lib\preprocessor-loader.js:9:25)
原因:没有原因,纯抽风,HX 关掉再开就好了。
异常:
Cannot set property 'xxx' of undefined;at pages/... onLoad function;at api request success callback function
原因:属性未定义,例如
data() {
return {
item: { }
}
}
而直接赋值 this.item.abc.xxx = '123';
解决:
data() {
return {
item: {
abc: ''
}
}
}
问:page 页面怎样修改 tabBar?
答:官方文档未给出答案,百度了一圈也无果(2018-10-23),但有人说小程序的 setTabBarBadge() 方法设置角标是可以用的。
坑:
VM1694:1 获取 wx.getUserInfo 接口后续将不再出现授权弹窗,请注意升级
参考文档: https://developers.weixin.qq.com/community/develop/doc/0000a26e1aca6012e896a517556c01
填坑:放弃使用 uni.getUserInfo 接口来获取用户信息,uni.login 可返回用于换取 openid / unionid 的 code,参:uni.login、 code2Session
坑:字符搜索(当前目录)(Ctrl+Alt+F)搜不出所有结果
填坑:顾名思义他只搜索当前目录,即当前打开文件所在目录,而非我误认为的整个项目根目录。在“项目管理器”中选中要搜索字符的目录即可。
坑:uni.navigateTo() 或 uni.redirectTo() 没反应
填坑:这两个方法不允许跳转到 tabbar 页面,用 uni.switchTab() 代替。
坑:使用“Ctrl+/”快捷键弹出“QQ五笔小字典”窗口
解决:打开QQ五笔“属性设置”,切换到“快捷键设置”选项卡,把“五笔小字典”前的勾取消(即使该组合键是设置为Ctrl+?)。
坑:<rich-text /> 中的 <img /> 太大,超出屏幕宽度
填坑:用正则表达式给 <img /> 加上最大宽度
data.data.Content = data.data.Content.replace(/\<img/gi, '<img style="max-width:100%;height:auto" ');
坑:无法重命名或删除目录或文件
填坑一:“以管理员身份运行”HBuilder X 后再试。
填坑二:关闭微信开发者工具、各种手机和模拟器后再试。
填坑三:打开“任务管理器”,结束所有“node.exe”进程后再试。
坑:
thirdScriptError
sdk uncaught third Error
(intermediate value).$mount is not a function
TypeError: (intermediate value).$mount is not a function
Page[pages/xxxx/xxxx] not found. May be caused by: 1. Forgot to add page route in app.json. 2. Invoking Page() in async task.
Page is not constructed because it is not found.
填坑:关闭微信开发者工具、各种手机和模拟器后,删除“unpackage”目录。
坑:
Unexpected end of JSON input;at "pages/news/view" page lifeCycleMethod onLoad function
SyntaxError: Unexpected end of JSON input
填坑:给 uni.navigateTo() 的 url 传参时,如果简单地将对象序列化 JSON.stringify(item),那么如果内容中包含“=”等 url 特殊字符,就会发生在接收页面 onLoad() 中无法获取到完整的 json 对象,发生异常。
uni.navigateTo({
url: "../news/view?item=" + JSON.stringify(item)
})
所以应该把参数值编码:
uni.navigateTo({
url: "../news/view?item=" + escape(JSON.stringify(item))
})
如果是一般的 web 服务器来接收,那么会自动对参数进行解码,但 uni-app 不会,如果直接使用:
onLoad(e) {
this.item = JSON.parse(e.item);
}
会发生异常:
Unexpected token % in JSON at position 0;at "pages/news/view" page lifeCycleMethod onLoad function
SyntaxError: Unexpected token % in JSON at position 0
需要解码一次:
onLoad(e) {
this.item = JSON.parse(unescape(e.item));
}
需要注意的是,unescape(undefined) 会变成 'undefined',如果要判断是否 undefined,应是 unescape 之前。
坑:图片变形
填坑:mode="widthFix"
坑:页面如何向 tabBar 传参
填坑:全局或缓存
坑:编译为 H5 后,出现:Access-Control-Allow-Origin
填坑:参阅
坑:编译为 H5 后,GET 请求的 URL 中出现“?&”
填坑 :客户端只求 DCloud 官方能够尽快修复这个 bug,IIS 端可以暂时用 URL 重写来防止报 400 错误,参此文。
坑:[system] errorHandler TypeError: Cannot read property 'forEach' of undefined
填坑:待填
在开发微信中的网页时,会遇到一些域名相关的配置:
① 公众号设置 - 功能设置 - 业务域名
② 公众号设置 - 功能设置 - JS接口安全域名
③ 接口权限 - 网页授权获取用户基本信息
④ 商户平台 - 产品中心 - 开发配置 - JSAPI支付授权目录
⑤ 小程序 - 开发 - 开发设置 - 业务域名
⑥ 公众号开发 - 基本设置 - IP白名单
第①种 业务域名:相对不重要,只是用来禁止显示“防欺诈盗号,请勿支付或输入qq密码”提示框,可配置 3 个二级或二级以上域名(个人理解是“非顶级域名”,即填写了 b.a.com 的话,对 c.b.a.com 不起作用,待测)。
我们网站的域名和公众号是没有绑定关系的,那么你在打开一个(可能是朋友分享的)网页时,跟哪个公众号的配置去关联呢,答案是 JS-SDK。
测试结果:由于一个月只有3次修改机会,这次先测二级域名,有效;再测顶级域名,有效;删除所有,仍有效。所以应该是缓存作用。过几天再试,然后下个月先测顶级域名,来确定直接填写顶级域名是否对所有二级域名有效。
第②种 JS接口安全域名:是配置所配置的域名下的网页可调用 JS-SDK。可配置 5 个一级或一级以上域名(个人理解是“任何级域名”,即填写了 b.a.com 对 c.b.a.com 也有效,但对 c.z.a.com 无效,待测。如果我们拥有顶级域名对应网站的控制权(上传验证文件到网站根目录),直接填写顶级域名即可)。
使用 JS-SDK 的每个网页都必须注入配置信息(wx.config),而之前必须获取 jsapi_ticket,jsapi_ticket api 的调用次数非常有限,必须全局缓存。而获取 jsapi_ticket 之前必须先获取 access_token,同样需要全局缓存。所以,我们专门做个接口,功能是传入需要使用 JS-SDK 的网页的 url,输出 wx.config 需要用到的配置信息,来实现在不同网页(网站)使用 JS-SDK。
第③种 网页授权域名:这是已认证的服务号才能享有的特权,主要作用是获取用户在该服务号中的 openid 和 unionid。可配置 1 个 2 个回调域名(可填写任意级别的域名,但仅对该域名的网页(网站)有效,若填写了 a.com 对 b.a.com 是无效的)。
因此,如果我们需要在不同二级域名甚至不同顶级域名下的网页(以下称之为活动页面)实现用户授权,需要做一个统一的代理授权页面(回调域名当然是填写这个页面所在的域名),引导用户依次打开:微信授权页面 - 代理授权页面 - 活动页面,根据开发说明文档,具体实现如下:
当用户第一次打开活动页面时,引导打开微信授权页面(https://open.weixin.qq.com/connect/oauth2/authorize),其中参数 redirect_uri 指定回调地址,即代理授权页面地址,参数 state 指定活动页面地址。微信授权页面返回 code 和 state,code 作为换取网页授权 access_token 的票据。到这一步,本来可以由代理授权页面直接拿这个 code 去换取 access_token、openid 和 unionid 了,但是由于当前用户还在 302 重定向过程中,将这些信息带入到活动页面时势必导致信息泄露,所以这里将 code 追加到 state 指定的网址上后重定向到活动页面,活动页面拿到 code 再通过服务器端向代理授权页面所在服务器请求 openid 和 unionid,并将它们保存于 Session 中视为用户登录。这样,服务号的 appid 和 secret 也能得到保护。代理授权页面请求的微信服务器接口地址是 https://api.weixin.qq.com/sns/oauth2/access_token。
注:网页授权 access_token 不同于 JS-SDK 中使用的全局唯一接口调用凭据 access_token,没有请求次数限制。
流程既然通了,实现逻辑可以这样设定:
活动页面首先判断 Session 中是否有 openid 或 unionid,若有表示已授权登录;没有再判断地址栏是否有 code 参数,若有则调用代理授权页面所在服务器的接口,用 code 换 openid 和 unionid;没有则直接重定向到代理授权页面,带上 state。用 code 换 openid 和 unionid 时若成功则保存至 Session,若失败则仍然重定向到代理授权页面,带上 state,特别注意 state 中的活动页面地址确保没有 code 参数。
第④种 JSAPI支付授权目录:涉及到微信支付时用到,顾名思义是固定某一个网站内的某个目录,以“/”结尾。最多可添加 5 个。如果支付页面在目录 https://www.a.com/b/ 下,那么可以填写 https://www.a.com/b/ 或 https://www.a.com/(建议后者),暂未测试填写 https://a.com/ 会不会起作用。涉及支付安全,建议设置支付页面的最深一层不可写的目录,以防目录内被上传后门文件带来的安全隐患。
第⑤种 小程序业务域名:任何需要在小程序的 web-view 组件中打开的网页,都必须配置小程序业务域名,限制 20 个。该域名要求必须 https,可填入“任何级域名”(建议填顶级域名,即填写了 a.com 对 b.a.com 也有效。如果我们拥有顶级域名对应网站的控制权(上传验证文件到网站根目录),直接填写顶级域名即可)。
第⑥种 IP白名单:仅填写管理全局 access_token 的中控服务器的 IP。
总结:在上述自定义接口部署完成后,如果微信中的网页想获取用户的 unionid,则不需要配置域名,直接使用统一的代理授权即可;如果需要使用 JS-SDK 功能,如分享、上传等等,则需要配置 JS 接口安全域名;如果有表单,最好配置一下业务域名。
本文系个人经验总结,部分结果未经证实,欢迎指正!QQ:940534113