微信网页应用开发完整教程
什么是微信网页应用?
微信网页应用(通常指在微信内置浏览器中打开的网页)是一种特殊的移动端网页,它最大的特点是可以深度集成微信的能力,
- 微信登录:让用户使用微信账号一键登录你的网站,无需注册。
- 微信支付:在网页内直接调用微信支付,完成交易闭环。
- 分享给好友/朋友圈:自定义分享标题、图片和描述,提升传播效果。
- 获取用户信息:在用户授权后,获取昵称、头像、性别等基本信息。
- 调用微信原生功能:如扫码、定位、拍照、选择图片等。
它就是一个“运行在微信里的、能调用微信能力的、有原生 App 体验感的网页”。
核心概念:JS-SDK
实现上述所有功能的核心是 微信 JS-SDK,它是一组由微信提供的 JavaScript 接口,让你可以在网页中调用微信的原生能力。
工作流程如下:
- 网页发起请求:你的网页 JS 代码想调用某个微信功能(获取地理位置)。
- 请求服务器:网页不能直接调用 JS-SDK,必须先向你的后端服务器发起一个请求,带上当前页面的 URL。
- 服务器获取签名:你的后端服务器根据微信官方提供的算法,使用你的
AppID、AppSecret、URL等参数生成一个签名。 - 服务器返回签名:后端将生成的签名返回给前端网页。
- 前端调用 SDK:前端网页使用微信提供的
wx.config或wx.ready方法,将签名等信息配置进去,验证通过后,就可以安全地调用wx.getLocation()等接口了。
开发前准备:公众号与配置
在开始写代码之前,你必须拥有一个微信公众平台账号。
步骤 1:注册公众号
- 服务号:适合企业,拥有微信支付、高级接口(如JS-SDK)等权限。个人无法注册。
- 订阅号:适合媒体、个人,没有微信支付和大部分高级接口权限。
推荐: 如果你要开发带有支付功能的网页应用,必须注册服务号。
步骤 2:获取开发者凭证
登录 微信公众平台,在“设置与开发” -> “基本配置”中找到:
- AppID (应用ID):公众号的唯一标识。
- AppSecret (应用密钥):用于获取访问令牌,务必保密!
步骤 3:配置网页授权域名
如果你的应用需要获取用户信息(如昵称、头像),必须配置网页授权域名。
- 在“设置与开发” -> “接口权限”中找到“网页授权”。
- 点击“修改”,将你的网页域名(
www.yourdomain.com)添加进去。注意: 只能配置顶级域名,不能配置子路径(如www.yourdomain.com/path是无效的)。
步骤 4:配置 JS-SDK 安全域名
这是调用 JS-SDK 的前提。
- 在“设置与开发” -> “公众号设置” -> “功能设置”中找到“JS-SDK接口安全域名”。
- 点击“配置”,将你的网页域名(
www.yourdomain.com)添加进去。
详细开发步骤
我们将以一个“获取地理位置”功能为例,走完整个开发流程。
第 1 步:后端开发(签名算法)
后端的核心任务是生成签名,你需要一个后端语言(如 Node.js, Java, PHP, Python 等)来实现。
签名算法步骤(官方文档):
- 获取 access_token:
- URL:
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET - 使用你的
AppID和AppSecret发起请求,获取access_token。有效期为 2 小时,需要缓存。
- URL:
- 获取 jsapi_ticket:
- URL:
https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi - 使用上一步获取的
access_token发起请求,获取jsapi_ticket。有效期为 2 小时,需要缓存。
- URL:
- 生成签名:
- 拼接字符串:
jsapi_ticket=JSAPI_TICKET&noncestr=NONCESTR×tamp=TIMESTAMP&url=URL - 对拼接好的字符串进行 SHA1 加密,得到的字符串就是
signature。
- 拼接字符串:
参数说明:
jsapi_ticket:从上一步获取。noncestr:随机字符串,长度建议为 32 位。timestamp:当前时间戳(秒)。url:当前网页的完整 URL,不包含 及其之后的部分,用户访问的是https://www.yourdomain.com/path?name=test#abc,url应该是https://www.yourdomain.com/path?name=test。
后端接口示例 (Node.js):
// server.js
const express = require('express');
const axios = require('axios');
const crypto = require('crypto');
const app = express();
// 缓存 access_token 和 jsapi_ticket
let accessToken = '';
let jsapiTicket = '';
let tokenExpires = 0;
let ticketExpires = 0;
async function getAccessToken() {
if (accessToken && Date.now() < tokenExpires) {
return accessToken;
}
const response = await axios.get(`https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=YOUR_APPID&secret=YOUR_APPSECRET`);
accessToken = response.data.access_token;
tokenExpires = Date.now() + (response.data.expires_in - 300) * 1000; // 提前5分钟过期
return accessToken;
}
async function getJsapiTicket() {
if (jsapiTicket && Date.now() < ticketExpires) {
return jsapiTicket;
}
const token = await getAccessToken();
const response = await axios.get(`https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=${token}&type=jsapi`);
jsapiTicket = response.data.ticket;
ticketExpires = Date.now() + (response.data.expires_in - 300) * 1000; // 提前5分钟过期
return jsapiTicket;
}
app.get('/get-signature', async (req, res) => {
const url = req.query.url; // 前端传来的当前页面URL
const noncestr = crypto.randomBytes(16).toString('hex');
const timestamp = Math.floor(Date.now() / 1000);
const ticket = await getJsapiTicket();
const string = `jsapi_ticket=${ticket}&noncestr=${noncestr}×tamp=${timestamp}&url=${url}`;
const signature = crypto.createHash('sha1').update(string, 'utf8').digest('hex');
res.json({
appId: 'YOUR_APPID',
timestamp: timestamp,
nonceStr: noncestr,
signature: signature
});
});
app.listen(3000, () => console.log('Server is running on port 3000'));
第 2 步:前端开发(调用 SDK)
前端相对简单,主要是引入微信 JS-SDK 库并调用接口。
-
引入 JS-SDK:有两种方式。
- 推荐方式(npm):
npm install weixin-js-sdk - 传统方式:在 HTML 中通过
<script>标签引入,微信官方会提供一个 JS 文件链接。
- 推荐方式(npm):
-
编写前端代码:
<!-- index.html -->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">微信网页应用示例</title>
<style>
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; }
#location-btn { padding: 10px 20px; font-size: 16px; cursor: pointer; }
#result { margin-top: 20px; padding: 10px; border: 1px solid #ccc; }
</style>
</head>
<body>
<h1>微信网页应用开发教程</h1>
<button id="location-btn">获取我的地理位置</button>
<div id="result"></div>
<!-- 引入微信 JS-SDK -->
<script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
<script>
document.addEventListener('DOMContentLoaded', () => {
const btn = document.getElementById('location-btn');
const resultDiv = document.getElementById('result');
btn.addEventListener('click', () => {
// 1. 向后端请求签名
// 当前页面的URL,确保与后端生成签名时使用的URL一致
const currentUrl = window.location.href.split('#')[0];
fetch(`/get-signature?url=${encodeURIComponent(currentUrl)}`)
.then(response => response.json())
.then(data => {
// 2. 配置 JS-SDK
wx.config({
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: data.appId,
timestamp: data.timestamp,
nonceStr: data.nonceStr,
signature: data.signature,
jsApiList: ['getLocation'] // 需要调用的JS接口列表,这里我们只调用地理位置
});
// 3. 准备调用接口
wx.ready(function () {
// 在这里调用需要初始化的接口
console.log('JS-SDK 初始化成功');
// 获取地理位置
wx.getLocation({
type: 'wgs84', // 默认为wgs84的gps坐标,如果要直接打开腾讯地图,请使用gcj02坐标
success: function (res) {
const latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90
const longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。
resultDiv.innerHTML = `获取成功!<br>纬度: ${latitude}<br>经度: ${longitude}`;
},
fail: function (res) {
resultDiv.innerHTML = `获取失败: ${res.errMsg}`;
}
});
});
// 4. 处理验证失败
wx.error(function (res) {
resultDiv.innerHTML = `JS-SDK 验证失败: ${res.errMsg}`;
console.error('wx.error', res);
});
})
.catch(error => {
resultDiv.innerHTML = `网络请求失败: ${error}`;
});
});
});
</script>
</body>
</html>
第 3 步:本地调试与上线
-
本地调试:由于微信 JS-SDK 的安全域名限制,你无法直接在
localhost上进行调试。- 解决方案:使用 ngrok 或 frp 等内网穿透工具,将你的本地开发服务器(如
localhost:3000)映射到一个公网域名(如https://xxxx.ngrok.io)。 - 将这个公网域名添加到公众号的“JS-SDK接口安全域名”和“网页授权域名”配置中,即可正常调试。
- 解决方案:使用 ngrok 或 frp 等内网穿透工具,将你的本地开发服务器(如
-
正式上线:将你的项目部署到云服务器(如阿里云、腾讯云、Vercel等),并将正式域名配置到公众号后台即可。
其他常用功能简介
微信登录与用户信息获取
这通过 OAuth2.0 网页授权流程实现。
- 引导用户授权:
- 构造一个 URL,让用户浏览器跳转过去。
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirectscope:snsapi_base:静默授权,不弹出授权页面,只能获取openid。snsapi_userinfo:弹出授权页面,用户同意后,可以获取nickname,avatar,sex等信息。
- 获取 code:用户授权后,微信会重定向到
redirect_uri,并在 URL 参数中带上code。 - 获取 access_token:你的后端服务器拿着
code去请求微信服务器,换取access_token和openid。 - 获取用户信息:
scope是snsapi_userinfo,再用access_token去请求用户信息接口,获取用户详情。
微信支付
流程更复杂,涉及多端交互。
- 前端发起支付请求:用户点击支付按钮。
- 后统统一下单:你的后端服务器调用微信支付的“统一下单”接口(
https://api.mch.weixin.qq.com/pay/unifiedorder),生成一个prepay_id。 - 后端生成支付参数:后端用
prepay_id和其他参数(appId,timeStamp,nonceStr,package,signType)再次生成一个签名。 - 前端调起支付:前端 JS-SDK 调用
wx.chooseWXPay(),将后端返回的参数传进去,弹出微信支付界面。 - 结果处理:支付结果通过微信服务器的异步通知(你的一个回调 URL)和前端的
wx.onMenuShareAppMessage事件来处理。
分享功能
分享功能分为两种:分享给好友/群聊,和分享到朋友圈。
- 分享给好友/群聊:使用
wx.updateAppMessageShareData。 - 分享到朋友圈:使用
wx.updateTimelineShareData。
两者都需要在 wx.ready 中调用,并且需要配置 jsApiList。
最佳实践与注意事项
- URL 必须精确:生成签名时使用的
url必须和用户访问的 URL 完全一致(包括 后面的参数)。 - 缓存 Token:
access_token和jsapi_ticket有有效期,务必在后端缓存,避免频繁请求微信服务器。 - 错误处理:始终关注
wx.error和 API 的fail回调,做好用户体验。 - 移动端优先:所有页面必须针对移动端进行优化,使用
viewport标签,采用响应式或流式布局。 - 性能优化:微信内置浏览器对性能有一定要求,注意图片压缩、代码分割等。
- 阅读官方文档:微信的文档是最终的权威,遇到问题多查阅 微信 JS-SDK 开发文档。
微信网页应用开发的核心是 “后端生成签名,前端调用 SDK”,虽然配置过程略显繁琐,但一旦打通,你就能将微信的海量用户和强大能力无缝集成到自己的产品中,创造出极具竞争力的移动端 Web 应用。
从最简单的地理位置功能开始,逐步尝试登录、分享、支付等功能,你会很快掌握这门技术,祝你开发顺利!
