- 小程序中如何加载使用第三方字体
简述:使用开启CORS的woff字体格式(或ttf)的https资源地址,使用[代码]wx.loadFontFace[代码] API(css原生[代码]@font-face[代码]语法)加载使用。 ⚠️ 注意:字体商用需授权许可,目前免费可商用的大部分字体,可见参考索引5。以下示例使用的是开源字体:得意黑和钉钉进步体。 1. wx.loadFontFace使用wx.loadFontFace 加载字体,配合wxss和wxml使用,参见文档 & 官方示例 // -- wxss -- // .DingTalk-JinBuTi { // font-family: 'DingTalk-JinBuTi'; // } wx.loadFontFace({ family: 'DingTalk-JinBuTi', source: 'url("https://xxx/font/DingTalk-JinBuTi.woff")', //此处需替换为真实字体地址 success(res) { console.log(res.status) }, fail: function (res) { console.log(res.status) }, complete: function (res) { console.log(res.status) } }); 注意: 格式支持常见的基本所有类型(ttf、woff、woff2(web主流)、otf、sfnt),建议格式为 TTF 和 WOFF(推荐),WOFF2 在低版本的 iOS 上会不兼容。字体链接仅支持https链接字体链接访问需满足浏览器同源策略,字体文件资源设置CORS的[代码]Access-Control-Allow-Origin[代码]为小程序域名:[代码]servicewechat.com[代码]或者*才可以。经过测试,ios和小米手机对于未设置CORS的字体文件仍然可以正常加载,荣耀和vivo无法正常加载,需要设置正确的CORS即可正常加载在加载成功之后,会自动刷新字体显示不需要设置downloadFile合法域名及业务域名。扩展:一次加载,全局使用如下在app.js中加载添加全局参数(global: true),即可在任意页面中的font-family中使用该字体。 onLaunch() { wx.loadFontFace({ family: 'DingTalk-JinBuTi', global: true, source: 'url("https://xxx/font/DingTalk-JinBuTi.woff")', //此处需替换为真实字体地址 success(res) { console.log(res.status) }, fail: function (res) { console.log(res.status) }, complete: function (res) { console.log(res.status) } }); }, 2. @font-face同css加载字体的规则,见MDN文档, 注意:字体链接访问需满足浏览器同源策略。支持常见格式。 @font-face { font-family: "SmileySans-Oblique"; src: url("https://xxx/font/SmileySans-Oblique.woff"); //此处需替换为真实字体地址 } .SmileySans-Oblique { font-family: 'SmileySans-Oblique'; } 扩展:全局使用在app.wxss中引入字体即可全局使用。 @font-face { font-family: "SmileySans-Oblique"; src: url("https://xxx/font/SmileySans-Oblique.woff"); //此处需替换为真实字体地址 } .SmileySans-Oblique { font-family: 'SmileySans-Oblique'; } 3. face-font base64 因源码过大致小程序增加包体积,暂不考虑。英文字体可以考虑。参见此。 扩展:在canvas中使用小程序canvas渲染时需要字体加载完成,css方式字体加载完成不容易监听,小程序文档提到可使用wx.loadFontFaced的回调中渲染canvas。参考文档及代码示例。 另外wxml-to-canvas中不支持font-family属性,可参考链接4修改源码实现。 参考wx.loadFontFace(Object object) | 微信开放文档微信小程序使用自定义字体的三种方法 - 掘金loadFontFace 支持全局生效 | 微信开放社区wxml-to-canvas没有fontWeight的相关支持? | 微信开放社区光明正大用字体——2023年“不要钱”的字体集合!哔哩哔哩bilibili[图片]
2023-03-21 - 上传的安全域名不能配置一级域名么?华为云的域名
后台已经配置uploadFile上传的顶级域名,为啥二级域名不能通过。[图片]
2024-05-13 - 微信小程序里一次 JSON.parse 解析错误问题的探究
问题描述 我们知道,在微信小程序里[代码]wx.request[代码]请求参数里的[代码]dataType[代码]默认是[代码]json[代码],意味着我们期望接口返回的数据格式是 JSON 文本,且系统会对返回的数据自动进行一次[代码]JSON.parse[代码]。因此,若接口返回的是个值为[代码]object[代码]的 JSON 文本,那么最终我们拿到的[代码]res.data[代码]应该是个 JavaScript 对象。 但是,一旦接口返回的数据里包含了行分隔符,在 iOS 系统上,就会出现一些问题。以下,我们将通过一个简单的示例来描述这个问题。 假设微信小程序项目里有以下代码: 请求[代码]http://windstone.cc/test[代码]接口,且假设接口返回的数据里包含了行分隔符,其 Unicode 码位为[代码]U+2028[代码]。 [代码]wx.request({ url: 'http://windstone.cc/test', success(res) { let data = res.data; console.log('typeof data', typeof data); if (typeof data === 'string') { for(let i = 0; i < data.length; i++) { console.log('字符是 ', data[i], 'Unicode 是 ', data[i].codePointAt(0).toString(16)); } } } }) [代码] 为了模拟接口返回里包含行分隔符的场景,我们将[代码]http://windstone.cc/test[代码]请求通过 Charles 的 Map Local 功能映射到如下所示的本地 JSON 文件上。这是个值为[代码]object[代码] 的 JSON 文本,[代码]object[代码]的[代码]x[代码]属性的值是个仅包含单个行分隔符的字符串,该行分隔符的 Unicode 码位是[代码]U+2028[代码]。PS: 行分隔符是不可见字符,不同的平台对该字符的展示方式不同,你可能看到的是个空字符串,或是个乱码字符,或是个换行。 [代码]{"x":" "} [代码] 在微信开发者工具中运行以上代码,会打印出如下数据: [代码]typeof data object [代码] 这表明接口返回的数据经过[代码]JSON.parse[代码]后,[代码]success[代码]回调里接收到的[代码]res.data[代码]是个 JavaScript 对象,这完全符合我们的预期。 但是,我们在 iOS 系统的手机中运行以上代码,结果却打印出了如下数据: [代码]typeof res.data string 字符是 { Unicode 是 7b 字符是 " Unicode 是 22 字符是 x Unicode 是 78 字符是 " Unicode 是 22 字符是 : Unicode 是 3a 字符是 " Unicode 是 22 字符是 Unicode 是 a 字符是 " Unicode 是 22 字符是 } Unicode 是 7d [代码] [代码]res.data[代码]返回的竟是个字符串!更加诡异的是,这个字符串居然跟接口返回的 JSON 文本有稍微的不同:字符串里的行分隔符([代码]U+2028[代码])不见了,原先行分隔符对应的位置上,新出现了个换行符([代码]U+000A[代码])!(换行符的 Unicode 码位转为 16 进制字符串的结果为[代码]a[代码],而行分隔符为[代码]2028[代码]) 这似乎与我们以前的开发经验有些相悖,而在此场景里,唯一与我们以前的开发场景不一样的地方是:接口返回的数据里包含了行分隔符。 于是,我们将返回数据修改成[代码]{"x":1}[代码]以验证是否是行分隔符搞的鬼。结果正如我们所猜想的,修改之后,无论是在微信开发者工具上还是 iOS 手机上,打印的都是[代码]typeof data object[代码]。 进一步探究 为了进一步探究出现这种情况的原因,我们将[代码]wx.request[代码]的代码稍加修改,将返回的数据格式由默认的[代码]json[代码]改为[代码]text[代码],如此就不会自动对返回的数据进行[代码]JSON.parse[代码]了。此外,我们再添加一些代码,来尝试手动进行[代码]JSON.parse[代码]并打印一些调试信息。 [代码]wx.request({ url: 'http://windstone.cc/test', dataType: 'text', // 设置返回的数据格式为 text success(res) { let data = res.data; console.log('typeof data', typeof data); if (typeof data === 'string') { for(let i = 0; i < data.length; i++) { console.log('字符是 ', data[i], 'Unicode 是 ', data[i].codePointAt(0).toString(16)); } // 尝试进行 JSON.parse try { data = JSON.parse(data); console.log('JSON.parse 解析成功', data); console.log('x 值的 Unicode 是 ', data.x.codePointAt(0).toString(16)); } catch(err) { console.log('JSON.parse 解析失败', err); } } } }) [代码] 运行以上代码,在微信开发者工具中,会打印出如下数据: [代码]typeof res.data string 字符是 { Unicode 是 7b 字符是 " Unicode 是 22 字符是 x Unicode 是 78 字符是 " Unicode 是 22 字符是 : Unicode 是 3a 字符是 " Unicode 是 22 字符是 Unicode 是 2028 字符是 " Unicode 是 22 字符是 } Unicode 是 7d JSON.parse 解析成功 {x: " "} x 值的 Unicode 是 2028 [代码] 通过打印结果可以发现,微信开发者工具中,返回的[代码]text[代码]格式数据里的行分隔符并没有被替换,且能正常进行[代码]JSON.parse[代码],解析后的对象里,[代码]x[代码]的值仍是个包含单个行分隔符([代码]U+2028[代码])的字符串。 但是在 iOS 手机中,会打印出如下数据: [代码]typeof res.data string 字符是 { Unicode 是 7b 字符是 " Unicode 是 22 字符是 x Unicode 是 78 字符是 " Unicode 是 22 字符是 : Unicode 是 3a 字符是 " Unicode 是 22 字符是 Unicode 是 a 字符是 " Unicode 是 22 字符是 } Unicode 是 7d JSON.parse 解析失败 [代码] 打印结果显示,iOS 手机中,返回的[代码]text[代码]格式数据[代码]res.data[代码]里的行分隔符([代码]U+2028[代码])被替换成了换行符([代码]U+000A[代码]),而且[代码]JSON.parse[代码]也会失败。 这个实验说明,当我们拿到[代码]res.data[代码]时,返回数据里的行分隔符已经被替换成了换行符,而之所以[代码]JSON.parse[代码]解析失败,也是因为要解析的字符串里包含了换行符。 鉴于此,我们还要继续弄清楚两个问题: 为什么 iOS 手机上接口返回的数据里,行分隔符会被替换为换行符? 为什么包含了换行符的字符串在进行[代码]JSON.parse[代码]时会报错? 弄清楚这两个问题之后,我们还需要解决一个问题,如何对[代码]res.data[代码]进行正确的[代码]JSON.parse[代码]? 原理解析 行分隔符被替换成换行符 针对第一个问题,ECMAScript Language Specification Edition 3 Final 的[代码]7.3 Line Terminators[代码]章节描述如下: Like white space characters, line terminator characters are used to improve source text readability and to separate tokens (indivisible lexical units) from each other. However, unlike white space characters, line terminators have some influence over the behaviour of the syntactic grammar. In general, line terminators may occur between any two tokens, but there are a few places where they are forbidden by the syntactic grammar. A line terminator cannot occur within any token, not even a string. Line terminators also affect the process of automatic semicolon insertion (section 7.8.5). The following characters are considered to be line terminators: Code Point Value Name Formal Name [代码]\u000A[代码] Line Feed [代码][代码] [代码]\u000D[代码] Carriage Return [代码][代码] [代码]\u2028[代码] Line separator [代码][代码] [代码]\u2029[代码] Paragraph separator [代码][代码] ES3 规范里说,[代码]U+2028[代码]和[代码]U+2029[代码]是行终止符,不能位于任何[代码]token[代码]之内,也不能出现在字符串之内。 Javascript parse error on ‘\u2028’ unicode character这篇文章里提到,JavaScript parser 针对任何未编码的[代码]U+2028[代码]和[代码]U+2029[代码],都以换行符对待。 目前我还没找到 iOS 系统里的 JavaScriptCore 将[代码]U+2028[代码]和[代码]U+2029[代码]替换为换行符的规范文档,但是在 ECMAScript Language Specification Edition 3 Final 的[代码]7.8.4 String Literals[代码]章节底部,有这么一句话: NOTE A LineTerminator character cannot appear in a string literal, even if preceded by a backslash . The correct way to cause a line terminator character to be part of the string value of a string literal is to use an escape sequence such as \n or \u000A. 根据这句话,JavaScriptCore 将[代码]U+2028[代码]和[代码]U+2029[代码]替换为换行符也是说得通的。 因此,iOS 系统里的 JavaScriptCore 可能仍然是按 ES3 的规范来处理行分隔符的,将其替换成了换行符,而且是在我们拿到[代码]res.data[代码]字符串之前。所以我们拿到[代码]res.data[代码]字符串时,字符串里已经没有行分隔符了,有的只是换行符。 BTW,在最新的 ECMA-262 11th Edition 规范里,为了与 JSON 保持一致,允许[代码]U+2028[代码]和[代码]U+2029[代码]出现在字符串里。 含有换行符的字符串 JSON.parse 出错 既然 iOS 的 JavaScriptCore 已经将行分隔符替换为了换行符,为什么仍然不可以[代码]JSON.parse[代码]呢? 查看 JSON 规范可知,JSON 文本的值可以是[代码]object[代码]、[代码]array[代码]、[代码]number[代码]、[代码]string[代码]、[代码]true[代码]、[代码]false[代码]、[代码]null[代码]。 接口返回的 JSON 文本经过上一步的替换后变成了这样:[代码]{"x":"↵"}[代码]。([代码]↵[代码]仅作为换行符的示意表示,实际上换行符是不可见的控制字符,无法显示在页面上) 如果[代码]{"x":"↵"}[代码]这个字符串是个有效的能被解析的 JSON 文本,则整个 JSON 文本的值就是个 JSON 的[代码]object[代码],[代码]object[代码]里有个[代码]x[代码]属性,其是个包含了单个换行符的[代码]string[代码]。但是,问题就出在这里,[代码]"↵"[代码]并不是个有效的 JSON[代码]string[代码]。 [图片] A string is a sequence of Unicode code points wrapped with quotation marks (U+0022). All code points may be placed within the quotation marks except for the code points that must be escaped: quotation mark(U+0022), reverse solidus (U+005C), and the control characters U+0000 to U+001F. There are two-character escape sequence representations of some characters. [代码]\"[代码] represents the quotation mark character (U+0022). [代码]\\[代码] represents the reverse solidus character (U+005C). [代码]\/[代码] represents the solidus character (U+002F). [代码]\b[代码] represents the backspace character (U+0008). [代码]\f[代码] represents the form feed character (U+000C). [代码]\n[代码] represents the line feed character (U+000A). [代码]\r[代码] represents the carriage return character (U+000D). [代码]\t[代码] represents the character tabulation character (U+0009). 按照Standard ECMA-404 The JSON Data Interchange Syntax里的规定,有效的 JSON [代码]string[代码]要求放置在两个[代码]"[代码]之间,且: [代码]"[代码]和[代码]\[代码]不能单独出现在两个[代码]"[代码]之内,需要使用[代码]\[代码]对其进行转义,比如[代码]\"[代码]表示单个字符[代码]"[代码],[代码]\\[代码]表示单个字符[代码]\[代码]。 [代码]\[代码]后紧跟着[代码]/[代码]、[代码]b[代码]、[代码]f[代码]、[代码]n[代码]、[代码]r[代码]、[代码]t[代码]也都各自表示特殊的字符。 两个[代码]"[代码]之内不能出现控制字符(Unicode 码位在[代码]U+0000[代码]~[代码]U+001F[代码]区间) 而 Unicode 码位为[代码]U+000A[代码]的换行符[代码]↵[代码]就是控制字符。因此,[代码]"↵"[代码]不是个有效的 JSON [代码]string[代码],进而[代码]{"x":"↵"}[代码]不是个有效的 JSON [代码]object[代码],最终导致[代码]JSON.parse[代码]失败。 说了这么多,不如用更简单的方式验证一下,在浏览器控制台输入以下代码观看结果: [代码]const a = '{"x":"\u000A"}' JSON.parse(a) // Uncaught SyntaxError: Unexpected token // in JSON at position 6 // at JSON.parse () // at :2:6 [代码] 由于字符串字面量要经过一层 JavaScript 解析,因此[代码]{"x":"\u000A"}[代码]经过 JavaScript 解析后,就变成了 JavaScript 字符串[代码]{"x":"↵"}[代码],而在将其[代码]JSON.parse[代码]时就报错了,提示[代码]↵[代码]是个不期望出现的[代码]token[代码]。 因此,之所以在对包含换行符的字符串进行[代码]JSON.parse[代码]时会出错,是因为换行符属于控制字符,不能出现在 JSON 文本的[代码]string[代码]里,否则该 JSON 文本就不是个有效的 JSON 文本,不能被成功解析。 现在,现象与原理我们都弄清楚了,下一步要做的就是如何正确地对包含换行符的数据进行[代码]JSON.parse[代码]了。 解决方案 再次查看下 JSON 规范里的[代码]string[代码],其不允许两个[代码]"[代码]之间出现控制字符,但其又说[代码]\n[代码]这个转义序列代表的是个换行符。这也就说,转义序列[代码]\n[代码]在 JSON 文本里代表的是换行符,而且会在[代码]JSON.parse[代码]时被解析成换行符这个字符。 因此,我们在[代码]JSON.parse[代码]之前,先通过正则匹配到换行符,将换行符替换为[代码]\n[代码],就可以顺利进行[代码]JSON.parse[代码]了。 [代码]wx.request({ url: 'http://windstone.cc/test', success(res) { let data = res.data; if (typeof data === 'string') { data = data.replace(/\n/g, '\\n'); // 此处将换行符替换成 \\n,即可顺利解析 try { data = JSON.parse(data); } catch(err) { console.log('JSON.parse 解析失败', err); } } } }) [代码] 这里要注意的是,[代码]\\n[代码]是个字符串字面量,会先被 JavaScript 解析得到 JavaScript 字符串[代码]\n[代码],再替换换行符。替换后的[代码]data[代码]即为[代码]{"x":"\n"}[代码],经过[代码]JSON.parse[代码]之后,即可得到 JavaScript 对象[代码]{x: '↵'}[代码]。 说明 本文里测试的 iOS 手机是 iPhone XS MAX 和 iPhone 11 Pro MAX,微信版本都是 7.0.14。 本文描述的问题只出现在 iOS 手机上,Android 手机没问题。 文章里所说的接口返回数据里包含行分隔符是指返回的 JSON 文本的[代码]string[代码]里包含行分隔符。 参考文档 ECMAScript Language Specification Edition 3 Final ECMA-262 11th Edition Javascript parse error on ‘\u2028’ unicode character JSON: The JavaScript subset that isn’t MDN - JSON.stringify - Issue with plain JSON.stringify for use as JavaScript Standard ECMA-404 The JSON Data Interchange Syntax
2020-08-16 - 自定义组件的默认display到底是什么?
我项目里包含了多个自定义组件,但是我发现一些组件的display默认是inline,一些默认是block,完全没发现有什么规律,这个到底在哪里控制的? 我翻遍了文档都没找到相关的说明,组件里只能定义内部元素的display,组件本身的display只能靠使用组件的页面控制。 我有一个card组件,我之前总是认为自定义组件的display默认是block,结果今天出现了很奇怪的margin无效,开始一直以为是margin塌陷和BFC的问题,搞了半天才发现这个组件被默认设置为行内元素了,我只能在小程序的app.wxss里全局设置card的display为block,虽然也管用,但是这个问题很迷。 目前问题是解决了,但还是很好奇微信自定义组件的默认display是哪里控制的?
2020-12-08 - 输入框文字上移?
input、textarea在 Android 机子会出现文字被键盘弹起顶出 input 框,有没有解决方案?
2022-08-16 - weapp-qrcode-canvas-2d在微信小程序中生成二维码,新版canvas-2d接口
weapp-qrcode-canvas-2d weapp-qrcode-canvas-2d 是使用新版canvas-2d接口在微信小程序中生成二维码(外部二维码)的js包。canvas 2d 接口支持同层渲染且性能更佳,建议切换使用,可大幅提升生成图片的速度。 仓库地址 weapp-qrcode-canvas-2d【码云gitee】 weapp-qrcode-canvas-2d【github】 [图片] 测试环境 微信小程序基础库版本:2.10.4 开发者工具版本:Stable 1.03.2101150 Usage 先在 wxml 文件中,创建绘制的 [代码]canvas[代码],并定义好 [代码]width[代码], [代码]height[代码], [代码]id[代码] , [代码]type[代码] ,其中type的值必须为[代码]2d[代码] [代码]<canvas type="2d" style="width: 260px; height: 260px;" id="myQrcode"></canvas> [代码] 安装方法1:直接引入 js 文件 直接引入 js 文件,使用 [代码]drawQrcode()[代码] 绘制二维码 [代码]// 将 dist 目录下,weapp.qrcode.esm.js 复制到项目中。路径根据实际引用的页面路径自行改变 import drawQrcode from '../../utils/weapp.qrcode.esm.js' [代码] 安装方法2:npm安装 [代码]npm install weapp-qrcode-canvas-2d --save [代码] // 然后需要在小程序开发者工具中:构建npm [代码]import drawQrcode from 'weapp-qrcode-canvas-2d' [代码] 安装完成后调用 例子1:没有使用叠加图片 [代码]const query = wx.createSelectorQuery() query.select('#myQrcode') .fields({ node: true, size: true }) .exec((res) => { var canvas = res[0].node // 调用方法drawQrcode生成二维码 drawQrcode({ canvas: canvas, canvasId: 'myQrcode', width: 260, padding: 30, background: '#ffffff', foreground: '#000000', text: 'abc', }) // 获取临时路径(得到之后,想干嘛就干嘛了) wx.canvasToTempFilePath({ canvasId: 'myQrcode', canvas: canvas, x: 0, y: 0, width: 260, height: 260, destWidth: 260, destHeight: 260, success(res) { console.log('二维码临时路径:', res.tempFilePath) }, fail(res) { console.error(res) } }) }) [代码] 例子2:使用叠加图片(在二维码中加logo) [代码]const query = wx.createSelectorQuery() query.select('#myQrcode') .fields({ node: true, size: true }) .exec((res) => { var canvas = res[0].node var img = canvas.createImage(); img.src = "/image/logo.png" img.onload = function () { // img.onload完成后才能调用 drawQrcode方法 var options = { canvas: canvas, canvasId: 'myQrcode', width: 260, padding: 30, paddingColor: '#fff', background: '#fff', foreground: '#000000', text: '123456789', image: { imageResource: img, width: 80, // 建议不要设置过大,以免影响扫码 height: 80, // 建议不要设置过大,以免影响扫码 round: true // Logo图片是否为圆形 } } drawQrcode(options) // 获取临时路径(得到之后,想干嘛就干嘛了) wx.canvasToTempFilePath({ x: 0, y: 0, width: 260, height: 260, destWidth: 600, destHeight: 600, canvasId: 'myQrcode', canvas: canvas, success(res) { console.log('二维码临时路径为:', res.tempFilePath) }, fail(res) { console.error(res) } }) }; }) [代码] API drawQrcode([options]) options Type: Object 参数 必须 说明 示例 canvas 必须 画布标识,传入 canvas 组件实例 canvasId 非 绘制的[代码]canvasId[代码] [代码]'myQrcode'[代码] text 必须 二维码内容 ‘123456789’ width 非 二维码宽度,与[代码]canvas[代码]的[代码]width[代码]保持一致 260 padding 非 空白内边距 20 paddingColor 非 内边距颜色 默认与background一致 background 非 二维码背景颜色,默认值白色 [代码]'#ffffff'[代码] foreground 非 二维码前景色,默认值黑色 [代码]'#000000'[代码] typeNumber 非 二维码的计算模式,默认值-1 8 correctLevel 非 二维码纠错级别,默认值为高级,取值:[代码]{ L: 1, M: 0, Q: 3, H: 2 }[代码] 1 image 非 在 canvas 上绘制图片,层级高于二维码,v1.1.1+版本支持。具体使用见:例子2 [代码]{imageResource: '', width:80, height: 80, round: true}[代码]
2023-04-02 - 修改wxbarcode,使用canvas 2d模式开发小程序条形码
最近在做项目时,使用wxbarcode开发条形码生成。在真机测试时,发现生成的条形码层级很高,有交互时会遮挡页面的其它元素。查询文档得知,是旧版的canvas接口不支持同层渲染导致的。所以我们这里修改一下wxbarcode的相关源码,使之适配新版的canvas 2d模式。 首先,找到源码的index.js。 找到这里: function barc(id, code, width, height) { barcode.code128(wx.createCanvasContext(id), code, convert_length(width), convert_length(height)) } 修改如下: function barc(ctx, code, width, height) { barcode.code128(ctx, code, convert_length(width), convert_length(height)) } 这里将旧版的获取 CanvasContext的接口改成新版的。然后找到barcode.js,里边的 Graphics.prototype._fillRect = function(x, y, width, height, color) { this.ctx.setFillStyle(color) this.ctx.fillRect(x, y, width, height) } 修改如下: Graphics.prototype._fillRect = function(x, y, width, height, color) { this.ctx.fillStyle = color; this.ctx.fillRect(x, y, width, height) } 然后找到大概第65行,新版的没有draw()方法,注释掉即可 [图片] 还有一个bug需要修改,将chr2改为chr1。具体原因可网上搜索一下,这里不做展开 if (shifter != -1) { result.push(shifter); result.push(codeValue(chr1)); } 至此,源码修改结束,构建npm。 下边,修改项目里的相关代码。 首先是wxml: <canvas id='barcode' type="2d"></canvas> 然后是wsxx: #barcode{ display: block; width: 600rpx; height: 140rpx; margin: 0 auto; position: relative; z-index: 1; } 接着改js: creatCode() { let query = wx.createSelectorQuery(); query.select("#barcode").fields({ node: true, size: true }).exec((res) => { const canvas = res[0].node; const ctx = canvas.getContext('2d'); const dpr = wx.getSystemInfoSync().pixelRatio canvas.width = res[0].width * dpr canvas.height = res[0].height * dpr ctx.scale(dpr, dpr) wxbarcode.barcode( ctx, "1234567890", 600, 140 ) }); }, 至此,所有的修改都已完成。 再说个题外话,如果条形码的内容较为简单,微信的scanCode接口,扫码条形码时一般不出错。一旦条码的内容过长,那么scanCode接口扫码就会出现偏差,这是因为咱们的条形码是CODE_128格式的,扫出来的可能是其它格式的。所以会出现跟预想不一样的结果。这里可以做下判断,如果扫出来的不是CODE_128格式的,提醒用户重新扫码。 不过,最终从用户体验角度出发,还是建议大家使用识别率更高的二维码。
2022-12-19 - 小程序解密手机号,隔一小段时间后,checksession:ok,但是解密失败
官方文档说,加密使用的session_key和解密使用的session_key必须一致,但是我第一次进小程序,不使用login,也一样拿加密数据,那谁知道加密的session_key是什么,我是真的懵..... 就算我提前使用login获取session_key,保存下来,能够解密成功,过了一小段时间之后重新获取,check没失效,却解密失败,如果check失效的话,那他又是用的session_key什么加密的呢
2020-06-04 - wx.checkSession通过但是获取手机号后的数据拿去解密总是失败?
在授权获取手机号并发给后端解密的时候总是解密失败!!! 但我认为我的代码流程是没有问题的。 我先wx.checkSession查看用户session_key是否过期,过期则执行wx.login重新登录刷新session。但是某个用户在checkSession时我得到的总是seccess,然后数据发给后端却解密失败!!(然而我认为用户登录态实际已经过期了,但checkSession总是给我错误的指引!) 后来我改进,在后端返回解密失败后我再执行一次wx.login登录并刷新session_key后并给用户抛出提示:请在此点击重试!。用户再次点击授权后就解密成功了!!! ps:难道微信官方对这个惊天大bug没有一点发现?? 真是让人头痛啊
2021-05-27