微信网页应用开发完整教程

什么是微信网页应用?

微信网页应用(通常指在微信内置浏览器中打开的网页)是一种特殊的移动端网页,它最大的特点是可以深度集成微信的能力

  • 微信登录:让用户使用微信账号一键登录你的网站,无需注册。
  • 微信支付:在网页内直接调用微信支付,完成交易闭环。
  • 分享给好友/朋友圈:自定义分享标题、图片和描述,提升传播效果。
  • 获取用户信息:在用户授权后,获取昵称、头像、性别等基本信息。
  • 调用微信原生功能:如扫码、定位、拍照、选择图片等。

它就是一个“运行在微信里的、能调用微信能力的、有原生 App 体验感的网页”。


核心概念:JS-SDK

实现上述所有功能的核心是 微信 JS-SDK,它是一组由微信提供的 JavaScript 接口,让你可以在网页中调用微信的原生能力。

工作流程如下:

  1. 网页发起请求:你的网页 JS 代码想调用某个微信功能(获取地理位置)。
  2. 请求服务器:网页不能直接调用 JS-SDK,必须先向你的后端服务器发起一个请求,带上当前页面的 URL。
  3. 服务器获取签名:你的后端服务器根据微信官方提供的算法,使用你的 AppIDAppSecretURL 等参数生成一个签名
  4. 服务器返回签名:后端将生成的签名返回给前端网页。
  5. 前端调用 SDK:前端网页使用微信提供的 wx.configwx.ready 方法,将签名等信息配置进去,验证通过后,就可以安全地调用 wx.getLocation() 等接口了。

开发前准备:公众号与配置

在开始写代码之前,你必须拥有一个微信公众平台账号。

步骤 1:注册公众号

  • 服务号:适合企业,拥有微信支付、高级接口(如JS-SDK)等权限。个人无法注册
  • 订阅号:适合媒体、个人,没有微信支付和大部分高级接口权限。

推荐: 如果你要开发带有支付功能的网页应用,必须注册服务号

步骤 2:获取开发者凭证

登录 微信公众平台,在“设置与开发” -> “基本配置”中找到:

  • AppID (应用ID):公众号的唯一标识。
  • AppSecret (应用密钥):用于获取访问令牌,务必保密!

步骤 3:配置网页授权域名

如果你的应用需要获取用户信息(如昵称、头像),必须配置网页授权域名。

  1. 在“设置与开发” -> “接口权限”中找到“网页授权”。
  2. 点击“修改”,将你的网页域名(www.yourdomain.com)添加进去。注意: 只能配置顶级域名,不能配置子路径(如 www.yourdomain.com/path 是无效的)。

步骤 4:配置 JS-SDK 安全域名

这是调用 JS-SDK 的前提。

  1. 在“设置与开发” -> “公众号设置” -> “功能设置”中找到“JS-SDK接口安全域名”。
  2. 点击“配置”,将你的网页域名(www.yourdomain.com)添加进去。

详细开发步骤

我们将以一个“获取地理位置”功能为例,走完整个开发流程。

第 1 步:后端开发(签名算法)

后端的核心任务是生成签名,你需要一个后端语言(如 Node.js, Java, PHP, Python 等)来实现。

签名算法步骤(官方文档):

  1. 获取 access_token
    • URL: https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
    • 使用你的 AppIDAppSecret 发起请求,获取 access_token有效期为 2 小时,需要缓存
  2. 获取 jsapi_ticket
    • URL: https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi
    • 使用上一步获取的 access_token 发起请求,获取 jsapi_ticket有效期为 2 小时,需要缓存
  3. 生成签名
    • 拼接字符串:jsapi_ticket=JSAPI_TICKET&noncestr=NONCESTR&timestamp=TIMESTAMP&url=URL
    • 对拼接好的字符串进行 SHA1 加密,得到的字符串就是 signature

参数说明:

  • jsapi_ticket:从上一步获取。
  • noncestr:随机字符串,长度建议为 32 位。
  • timestamp:当前时间戳(秒)。
  • url当前网页的完整 URL,不包含 及其之后的部分,用户访问的是 https://www.yourdomain.com/path?name=test#abcurl 应该是 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}&timestamp=${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 库并调用接口。

  1. 引入 JS-SDK:有两种方式。

    • 推荐方式(npm)npm install weixin-js-sdk
    • 传统方式:在 HTML 中通过 <script> 标签引入,微信官方会提供一个 JS 文件链接。
  2. 编写前端代码

<!-- 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 上进行调试。

    • 解决方案:使用 ngrokfrp 等内网穿透工具,将你的本地开发服务器(如 localhost:3000)映射到一个公网域名(如 https://xxxx.ngrok.io)。
    • 将这个公网域名添加到公众号的“JS-SDK接口安全域名”和“网页授权域名”配置中,即可正常调试。
  • 正式上线:将你的项目部署到云服务器(如阿里云、腾讯云、Vercel等),并将正式域名配置到公众号后台即可。


其他常用功能简介

微信登录与用户信息获取

这通过 OAuth2.0 网页授权流程实现。

  1. 引导用户授权
    • 构造一个 URL,让用户浏览器跳转过去。
    • https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect
    • scope:
      • snsapi_base:静默授权,不弹出授权页面,只能获取 openid
      • snsapi_userinfo:弹出授权页面,用户同意后,可以获取 nickname, avatar, sex 等信息。
  2. 获取 code:用户授权后,微信会重定向到 redirect_uri,并在 URL 参数中带上 code
  3. 获取 access_token:你的后端服务器拿着 code 去请求微信服务器,换取 access_tokenopenid
  4. 获取用户信息scopesnsapi_userinfo,再用 access_token 去请求用户信息接口,获取用户详情。

微信支付

流程更复杂,涉及多端交互。

  1. 前端发起支付请求:用户点击支付按钮。
  2. 后统统一下单:你的后端服务器调用微信支付的“统一下单”接口(https://api.mch.weixin.qq.com/pay/unifiedorder),生成一个 prepay_id
  3. 后端生成支付参数:后端用 prepay_id 和其他参数(appId, timeStamp, nonceStr, package, signType)再次生成一个签名。
  4. 前端调起支付:前端 JS-SDK 调用 wx.chooseWXPay(),将后端返回的参数传进去,弹出微信支付界面。
  5. 结果处理:支付结果通过微信服务器的异步通知(你的一个回调 URL)和前端的 wx.onMenuShareAppMessage 事件来处理。

分享功能

分享功能分为两种:分享给好友/群聊,和分享到朋友圈。

  • 分享给好友/群聊:使用 wx.updateAppMessageShareData
  • 分享到朋友圈:使用 wx.updateTimelineShareData

两者都需要在 wx.ready 中调用,并且需要配置 jsApiList


最佳实践与注意事项

  1. URL 必须精确:生成签名时使用的 url 必须和用户访问的 URL 完全一致(包括 后面的参数)。
  2. 缓存 Tokenaccess_tokenjsapi_ticket 有有效期,务必在后端缓存,避免频繁请求微信服务器。
  3. 错误处理:始终关注 wx.error 和 API 的 fail 回调,做好用户体验。
  4. 移动端优先:所有页面必须针对移动端进行优化,使用 viewport 标签,采用响应式或流式布局。
  5. 性能优化:微信内置浏览器对性能有一定要求,注意图片压缩、代码分割等。
  6. 阅读官方文档:微信的文档是最终的权威,遇到问题多查阅 微信 JS-SDK 开发文档

微信网页应用开发的核心是 “后端生成签名,前端调用 SDK”,虽然配置过程略显繁琐,但一旦打通,你就能将微信的海量用户和强大能力无缝集成到自己的产品中,创造出极具竞争力的移动端 Web 应用。

从最简单的地理位置功能开始,逐步尝试登录、分享、支付等功能,你会很快掌握这门技术,祝你开发顺利!