微信公众号与小程序_weixin open platform
-
一、微信公众号开发常见问题及注意事项
微信网页开发 / 网页授权
-
公众号开发基础
- 开发前准备
- 配置服务器IP白名单
- 申请开发所需接口权限
- 开发前准备
-
公众号H5获取OpenID流程
-
OAuth2.0****授权流程
- 引导用户访问授权页面
其中REDIRECT_URI 才是我们前端的页面地址-通过下面方式进入我们的页面链接中会自动加上code的参数直接读取即可(如果有其他的参数避免使用code字段)
// 授权URL示例const authUrl = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${APPID}&redirect_uri=${encodeURIComponent(REDIRECT_URI)}&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect`;
- 用户同意授权后,获取code
- 通过code换取access_token和OpenID
// 通过code调用后端接口获取access_token和OpenIDapp.get(\'/getOpenid\', async (req, res) => { const { code } = req.query; const url = `https://api.weixin.qq.com/sns/oauth2/access_token?appid=${APPID}&secret=${SECRET}&code=${code}&grant_type=authorization_code`; const response = await axios.get(url); const { openid } = response.data; res.send(openid);});
- 注意事项
- redirect_uri需要在公众号后台配置白名单
- scope参数选择:snsapi_base(仅获取OpenID)或snsapi_userinfo(获取用户信息)
- 前端应避免直接处理敏感信息,建议通过后端代理请求
-
-
调用微信API
微信网页开发 / JS-SDK说明文档
- **绑定域名:**登录微信公众平台,进入 “公众号设置” 的 “功能设置”,填写 “JS 接口安全域名”。
- 引入 JS 文件:在需要调用 JS 接口的页面引入
http://res.wx.qq.com/open/js/jweixin-1.2.0.js
,支持使用 AMD/CMD 标准模块加载方法加载 - **注入权限验证配置:**通过
wx.config
接口注入配置信息,同一个 url 仅需调用一次。
wx.config({ debug: true, // 开启调试模式 appId: \'\', // 必填,公众号的唯一标识 timestamp: , // 必填,生成签名的时间戳 nonceStr: \'\', // 必填,生成签名的随机串 signature: \'\',// 必填,签名 jsApiList: [] // 必填,需要使用的JS接口列表});// 除了 jsApiList 填自己需要使用的接口外,其余参数通过后端接口获取(具体接口查看上面超链接)
- 处理成功验证:通过
ready
接口处理配置信息验证成功后的操作,所有接口调用都必须在 config 接口获得结果之后。
wx.ready(function(){ // 在此处调用相关接口});
- 处理失败验证:通过
error
接口处理配置信息验证失败的情况。
wx.error(function(res){ // 查看具体错误信息});
接口调用说明
所有接口通过
wx
对象(也可使用jWeixin
对象)来调用,参数是一个对象,除了每个接口本身需要传的参数之外,还有success
(接口调用成功回调)、fail
(接口调用失败回调)、complete
(接口调用完成回调)、cancel
(用户点击取消时回调,仅部分接口用到)、trigger
(监听 Menu 中的按钮点击时触发,仅支持 Menu 相关接口)等通用参数。常见接口示例
- 基础接口:判断当前客户端版本是否支持指定 JS 接口,如检测是否支持选择图片接口。
wx.checkJsApi({ jsApiList: [\'chooseImage\'], success: function(res) { // 以键值对的形式返回,可用的api值为true,不可用为false }});
- 分享接口:获取 “分享到朋友圈” 按钮点击状态及自定义分享内容。
wx.onMenuShareTimeline({ title: \'\', // 分享标题 link: \'\', // 分享链接 imgUrl: \'\', // 分享图标 success: function () { // 用户确认分享后执行的回调函数 }, cancel: function () { // 用户取消分享后执行的回调函数 }});
- 拍照与选图接口:调用系统相机拍照或从相册选图。
wx.chooseImage({ count: 1, // 最多可以选择的图片张数,默认1 sizeType: [\'original\', \'compressed\'], // 可以指定是原图还是压缩图,默认二者都有 sourceType: [\'album\', \'camera\'], // 可以指定来源是相册还是相机,默认二者都有 success: function (res) { var localIds = res.localIds; // 返回选定照片的本地ID列表,localId可以作为img标签的src属性显示图片 }});
- 位置接口:获取用户位置信息。
wx.getLocation({ type: \'wgs84\', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入\'gcj02\' success: function (res) { var latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90 var longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。 }});
-
公众号开发常见问题
- JS-SDK权限验证失败
- 检查config接口注入的参数是否正确
- 确认jsapi_ticket是否有效(有效期7200秒)
- 注意url必须是调用JS-SDK页面的完整URL
- 跨域问题
- 公众号页面默认不支持跨域请求
- 解决方案:使用JSONP、CORS或通过后端代理
- 缓存问题
- 微信内置浏览器对静态资源缓存严重
- 建议在URL后添加版本号:
script.js?v=1.0.1
- JS-SDK权限验证失败
-
公众号支付集成(待完善)
- 商户号申请与配置
- JSAPI支付流程
- 支付结果异步通知处理
二、uni-app小程序开发常见问题及注意事项
iOS特有问题
- 日期解析问题
// iOS不支持YYYY-MM-DD格式const date = new Date(\'2023-01-01\') // Android正常,iOS无效// 解决方案const date = new Date(\'2023/01/01\') // 统一使用斜杠分隔
- 输入框聚焦问题
/* iOS键盘弹出时页面错位 */input { -webkit-user-select: auto; /* 解决iOS12+输入框无法聚焦 */}
- 弹性滚动
.container { -webkit-overflow-scrolling: touch; /* iOS弹性滚动 */}
Android特有问题
图片加载
// Android可能无法加载本地图片
键盘遮挡
// manifest.json配置\"app-plus\": { \"softinputMode\": \"adjustResize\" // 自动调整窗口大小}
长按菜单问题
/* 禁用Android长按菜单 */* { -webkit-touch-callout: none; -webkit-user-select: none;}// user-select 默认是禁止长按选中文字的,* { user-select:text; // 允许长按选择文字 }
-
uni-app基础
- 一次开发多端发布的原理
- 目录结构与文件规范
- 条件编译语法
使用 uni.navigateTo 可以进行页面通信
// 在起始页面跳转到test.vue页面,并监听test.vue发送过来的事件数据uni.navigateTo({ url: \'pages/test?id=1\', // 调用通信事件对象 events: { // 获取下级页面参数: // 为指定事件添加一个监听器,获取被打开页面传送到当前页面的数据 // 注意看下级页面中所对应的函数名,你可以定义多个方法去管理传递的参数 acceptDataFromOpenedPage: function(data) { // 对数据做处理 console.log(data) }, someEvent: function(data) { // 对数据做处理 console.log(data) } }, // 发送通信方法 success: function(res) { // 通过eventChannel向被打开页面传送数据 // 其中含有两个参数,第一个是接收的函数名,第二个则是需要携带的参数 res.eventChannel.emit(\'acceptDataFromOpenerPage\', { data: \'data from starter page\' }) }})// 在test.vue页面,向起始页通过事件传递数据// 此方法不是一定要在 onLoad 内调用,哪里需要哪里调onLoad: function(option) { // 此处声明只是为了显示看起来简洁一点 const eventChannel = this.getOpenerEventChannel(); // emit 代表的就是向上一个页面传递需要更新的数据 eventChannel.emit(\'acceptDataFromOpenedPage\', {data: \'data from test page\'}); // 接收上个页面传递的数据 // 监听acceptDataFromOpenerPage事件,获取上一页面通过eventChannel传送到当前页面的数据 eventChannel.on(\'acceptDataFromOpenerPage\', function(data) { // 对数据做处理 console.log(data) })}
-
小程序开发常见问题
- 生命周期管理
- 应用、页面生命周期函数的区别
- 明确
onLoad
(页面加载,只执行一次) vsonShow
(页面显示/切入前台,每次都可能执行)的区别。 - 强调
onLoad
参数(options
)获取的是打开当前页面路径中的query
参数。 - 避免在
onLoad
/onShow
中进行耗时操作阻塞页面渲染。复杂计算或网络请求可考虑异步或使用setTimeout
/nextTick
。 - 避免在onLoad中进行复杂计算
- 明确
- 应用、页面生命周期函数的区别
- 性能优化
- 减少setData的数据量
- 合理使用v-if和v-show
- 避免在循环中使用内联样式
- 生命周期管理
-
uni-app跨平台兼容问题
- API兼容性
- 使用uni API替代原生API
-
// 正确写法uni.request({ url: \'https://api.example.com\', success: (res) => { console.log(res.data); }});
- 样式差异
- rpx与px的转换
- 不同平台导航栏高度差异
-
// 获取导航栏高度示例const info = uni.getSystemInfoSync();const navHeight = info.statusBarHeight + 44; // 44为默认导航栏高度
- 条件编译
-
// #ifdef H5console.log(\'这是H5环境\');// #endif// #ifdef MP-WEIXINconsole.log(\'这是微信小程序环境\');// #endif
-
- API兼容性
-
微信小程序特有问题
- 插件使用
- 地图、客服、直播等插件集成
- 插件使用前需要在app.json中声明
- 小程序审核规则
- 避免诱导分享、强制关注等违规行为
- 支付、内容审核等功能需符合规范
- 插件使用
小程序特有API
uni.navigateToMiniProgram({ appId: \'\', path: \'pages/index/index?id=123\', extraData: { \'data1\': \'test\' }, success(res) { // 打开成功 }})
需提前向用户发起授权请求 uni.authorize(OBJECT) | uni-app官网
很多API是需要配置的比如定位,后台定位(还需额外在微信后台申请使用权限)……, 详见:manifest.json 应用配置 | uni-app官网
微信小程序环境判断是开发版还是体验版本
// #ifdef MP-WEIXIN// ---------------- 根据微信开发环境配置请求地址 --------------------// 获取当前帐号信息const accountInfo = uni.getAccountInfoSync();// 还能拿到APPid等信息 console.log(accountInfo)// env类型 develop:开发版、trial:体验版、release:正式版const envWx = accountInfo.miniProgram.envVersion;if (envWx === \'release\') { console.log(\'正式版\');} else { console.log(\'开发版\',\'体验版\');}// #endif__wxConfig.envVersion 有三个值release(正式版) develop(开发版)trial(体验版)
直接console.log(__wxConfig);
-
分包加载
分包官方文档
项目目录结构(分包)
├── pages (主包 1.2MB) │ ├── 首页 │ ├── 登录页 │ └── 公共组件 ├── pages-repair (报修流程分包) ├── pages-payment (缴费分包) └── pages-activity (独立分包:社区活动)
- 主包大小限制2MB,建议使用分包
- 所有分包总和上限20MB(原主包仅2MB),支持更复杂功能。
- 配置pages.json实现分包
分包的两种类型与配置
1. 普通分包
- 特点:依赖主包运行,可共享主包公共资源(如工具类、组件)。
- 配置示例(
app.json
):
{ \"subPackages\": [{ \"root\": \"userCenter\", // 分包根目录 \"pages\": [\"profile\", \"settings\"], // 分包页面 \"name\": \"user\" // 分包别名(预下载用) }]}
2. 独立分包
- 特点:无需主包即可独立运行,启动速度更快(如活动页、功能模块)。
- 限制:
- ❌ 不可引用主包资源(需完全自包含)
- ❌ 不可使用
App()
生命周期(主包定义)。
- 配置:添加
\"independent\": true
:
{ \"root\": \"promotion\", \"pages\": [\"campaign\"], \"independent\": true // 独立分包}
分包类型对比
类型 依赖主包 资源引用 适用场景 普通分包 ✔️ 可引用主包 功能模块(如购物车) 独立分包 ❌ 完全独立 营销活动页、独立工具 三、关键技术细节
- 文件引用规则
- 主包:可被所有分包引用(组件、JS工具函数)。
- 分包间:禁止相互引用资源(如分包A无法调用分包B的JS)。
- 例外:通过分包异步化(需基础库≥2.11.1)可跨分包调用。
- 路由跳转
-
主包 → 分包:路径需包含分包根目录:
-
wx.navigateTo({ url: \'/userCenter/profile\' })
-
独立分包 → 主包:需先下载主包(用户无感知)。
-
- 预加载机制 在
app.json
中配置preloadRule
,进入特定页面时自动加载目标分包:
\"preloadRule\": { \"pages/index/index\": { // 触发页面 \"packages\": [\"userCenter\"], // 预下载分包 \"network\": \"wifi\" // 仅WiFi下加载 }}
三、开发工具与调试技巧
-
开发工具推荐
- HBuilderX:官方推荐的uni-app开发工具
- 微信开发者工具:小程序调试与发布
- VS Code:代码编辑与插件生态
-
调试技巧
- 小程序真机调试
- H5端Chrome开发者工具调试-公众号页面也可以使用微信开发者工具调试(需要对应微信后台添加为开发者)
- 使用console.log和uni.reportAnalytics埋点
-
// 添加调试面板// main.jsimport VConsole from \'vconsole\'process.env.NODE_ENV !== \'production\' && new VConsole()
-
性能检测工具
- 微信开发者工具性能分析面板
-
代码组织规范
src/├── common # 通用代码│ ├── api # 接口封装│ ├── utils # 工具函数│ └── style # 全局样式├── components # 通用组件├── pages # 页面组件├── static # 静态资源└── store # 状态管理
四、安全与部署注意事项
-
数据安全
- 避免在URL中传递敏感参数(微信小程序和公众号前端不能出现access_token)
- 使用HTTPS协议(http在IOS端无法访问)
-
部署流程
- 小程序:代码上传→审核→发布
- 公众号:服务器配置→域名备案→代码部署
-