news 2026/7/11 5:31:27

微信公众号开发教程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
微信公众号开发教程

介绍

微信公众号开发文档:服务号介绍 | 微信服务号文档

微信公众号管理后台界面:微信公众平台

微信公众号测试号管理后台界面:微信公众平台

微信开发者工具下载地址:微信开放文档

开发笔记参考:https://blog.csdn.net/midyear/category_12378053.html

微信开发者工具使用

  • 下载地址:微信开放文档
  • 使用流程:打开【微信开发者工具】,选择【公众号网页调试】,将调试页面地址复制到如下即可本地调试页面

内网穿透工具

使用 cploar ,官网地址:cpolar官网-安全的内网穿透工具 | 无需公网ip | 远程访问 | 搭建网站

什么是内网穿透工具:

  • 在微信开发中我们必须将代码部署在公网服务器上才能调试(说白了就是需要微信端能够调用到你的服务器)
  • 内网穿透工具能够将本地端口映射到它提供的一个公网域名上,通过访问这个域名来实现本地方法的调用

公众号测试号配置

  1. URL 和 Token 配置
url: 必须以http://或https://开头,分别支持80端口和443端口 URL规范:比如项目的基础目录为 www.abc.com/wechat/,则URL地址为 www.abc.com/wechat token: 可由开发者可以任意填写,用作生成签名(该Token会和接口URL中包含的Token进行比对,从而验证安全性)

  1. 配置 JS接口安全域名
JS接口安全域名: 就是当我们调用微信开发的JS接口时,使用的域名必须与配置的 JS接口安全域名一致 这个域名可以不与上面的URL一致

  1. 配置 授权回调页面域名
授权回调页面域名: 当我们在跳转的页面中需要调用微信公众号的接口,就必须配置这个域名地址 这个域名可以不与上面的URL一致 具体使用细节,参考:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html

  1. 在当前测试号页面可以看到 appId 和 secret ,配置完后就可以在项目中使用微信公众号测试号了。

公众号配置

  1. 在公众号中配置 URL 和 token,在【基本配置】中配置

  1. 配置 JS域名地址 和 授权回调域名地址,在【公众号设置】-【功能设置】中配置

  1. 在配置 JS域名地址 和 授权回调域名地址还需要在服务上配置一个txt文件,然后通过配置的域名 + xxx.txt能访问到。通常这个可以使用 nginx 转发实现。

    1. nginx 配置。将文件放置在 d:/webapps/wx/目录下
location /MP_verify_n5GSFAcyM6FNnI9L.txt { alias d:/webapps/wx/; index MP_verify_n5GSFAcyM6FNnI9L.txt; }

微信认证接口

在配置 URL 对应的 controller 下需要添加微信认证,认证接口是一个get请求且路径只能配置为 /

/** * 微信认证 * * @param signature * @param timestamp * @param nonce * @param echostr * @return */ @GetMapping("/") @ResponseBody public String authWechat(String signature, String timestamp, String nonce, String echostr) { log.info("微信请求参数:[signature={}, timestamp={}, nonce={}, echostr={}]", signature, timestamp, nonce, echostr); if (CommonUtil.isAnyBlank(signature, timestamp, nonce, echostr)) { throw new RuntimeException("请求参数非法!"); } if (!checkSignature(signature, timestamp, nonce)) { throw new RuntimeException("请求参数非法!"); } return echostr; } /** * 检查signature * * @param timestamp * @param nonce * @return */ public boolean checkSignature(String signature, String timestamp, String nonce) { StringBuilder stringBuilder = new StringBuilder(); // 自然排序,字符串拼接 Stream.of(token, timestamp, nonce) .sorted() .forEach(stringBuilder::append); String encryptSHA1 = CommonUtil.encryptSHA1(stringBuilder.toString()); return Objects.equals(encryptSHA1, signature); }
  • CommonUtil工具类
public class CommonUtil { /** * 是否存在空白的数据 * * @param params * @return */ public static boolean isAnyBlank(String... params) { for (String param : params) { if (!StringUtils.hasText(param)) { return true; } } return false; } /** * sha1 加密 * * @param str * @return */ public static String encryptSHA1(String str) { try { MessageDigest sha1 = MessageDigest.getInstance("SHA-1"); byte[] hashedBytes = sha1.digest(str.getBytes()); StringBuilder sb = new StringBuilder(); for (byte b : hashedBytes) { sb.append(String.format("%02x", b)); } return sb.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return null; } }

微信事件处理接口

在配置 URL 对应的 controller 下需要添加微信事件处理,认证接口是一个post请求且路径只能配置为 /

/** * 接收普通消息/事件 * * @param request * @return */ @PostMapping("/") @ResponseBody public String receiveMessage(HttpServletRequest request) { Map<String, String> map = new HashMap<>(); try (ServletInputStream inputStream = request.getInputStream()) { SAXReader saxReader = new SAXReader(); Document document = saxReader.read(inputStream); // 获取root Element root = document.getRootElement(); // 获得所有子节点 List<Element> elements = root.elements(); for (Element element : elements) { map.put(element.getName(), element.getStringValue()); } } catch (IOException | DocumentException e) { throw new RuntimeException(e); } System.out.println(map); // 回复消息 return replyMessage(map); } /** * 回复消息 * * @param map * @return */ private String replyMessage(Map<String, String> map) { String msgType = map.get("MsgType"); String message = ""; switch (msgType) { case "text": // TODO 消息 break; case "event": // TODO 事件 break; default: message = commonReply(map, "欢迎你使用公众号!"); break; } return message; }
  • 解析 xml 使用到了 xstream , maven依赖
<dependency> <groupId>com.thoughtworks.xstream</groupId> <artifactId>xstream</artifactId> <version>1.4.20</version> </dependency>
  • xstream拓展,除了解析 xml ,它还提供了java对象转 xml,代码如下:
    • 代转 xml 的对象
@Data @XStreamAlias("xml") public class TextMessage { /** * 接收方账号 */ @XStreamAlias("ToUserName") private String toUserName; /** * 开发者微信号 */ @XStreamAlias("FromUserName") private String fromUserName; /** * 消息创建时间 (整型) */ @XStreamAlias("CreateTime") private Long createTime; /** * 消息类型 */ @XStreamAlias("MsgType") private String msgType; /** * 回复的消息内容 */ @XStreamAlias("Content") private String content; }
    • 在实际代码中转 xml
private String commonReply(Map<String, String> map, String content) { TextMessage textMessage = new TextMessage(); textMessage.setToUserName(map.get("FromUserName")); textMessage.setFromUserName(map.get("ToUserName")); textMessage.setMsgType("text"); textMessage.setCreateTime(System.currentTimeMillis() / 1000); textMessage.setContent(content); // 将java对象转换成xml对象 XStream xStream = new XStream(); xStream.processAnnotations(TextMessage.class); return xStream.toXML(textMessage); }

UnionID、OpenID、AppID区别

UnionID:在微信公众平台和微信开放平台中,对于同一个微信用户,无论其通过多少个不同的应用(App)或公众号登录,都会对应一个唯一的 UnionID
OpenID:每个应用(App)或公众号下,同一个微信用户的OpenID是不同的。这意味着即使同一个用户在不同的应用或公众号中登录,每个应用或公众号会为该用户分配一个独特的OpenID

AppID:每个微信应用(包括小程序、公众号等)都有一个唯一的appID,用于标识该应用

遇到的问题

前后端部署在两个服务器存在跨域问题

当前后端部署在两个服务器中,会存在跨域问题,这个时候可以在 controller 上面配置@CrossOrigin注解,从而允许来自该域名的跨域请求

@RestController @RequestMapping("/wechat/") @CrossOrigin(origins = "http://net.abc.com") // 允许来自该域名的跨域请求 public class WxBaseConfigController { ... }

微信扫描生成的二维码

微信扫描生成的二维码有两种情况:

  • 已经关注了公众号,这时候扫描会进入【微信事件处理接口】,条件为
// xxx 表示生成二维码携带的内容 if ("subscribe".equals(map.get("Event")) && Objects.equals(map.get("EventKey"), "xxx")) { // TODO 业务处理 }
  • 未关注公众号,这个时候扫描也会进入【微信事件处理接口】,但条件变为
// 此时 EventKey 的内容等于 qrscene_ + xxx,其中xxx为二维码携带的内容 if ("SCAN".equals(map.get("Event")) && Objects.equals(map.get("EventKey"), "qrscene_xxx")) { // TODO 业务处理 }
  • 生成公众号二维码参考:生成带参数的二维码 | 微信服务号文档

微信公众号将当前页面转成图片并下载

前置条件:微信公众号前端使用的是 vue3 写的

我使用的是 vue 的 html2canvas 实现的,部分代码如下:

<script setup lang="ts"> import html2canvas from "html2canvas"; const btnClickDownload = () => { var content = document.getElementById("flexGird"); if (content) { app.data.showPic = true; html2canvas(content).then(canvas => { //添加属性 canvas.setAttribute('id', 'thecanvas'); var base64Image = document.getElementById('base64Img'); const img = canvas.toDataURL('image/png'); // 将canvas转换为base64图片格式 if (base64Image) { base64Image.setAttribute("src", img); } }); } }; </script> <template> <div> <div class="container" id="flexGird"> <div>需要生成图片的页面</div> </div> <div class="btn-box"> <div class="button" @click="btnClickDownload">下载图片</div> </div> </div> </template> <style scoped> </style>

IP不在白名单中

在对接微信公众号时调用接口报错:"errmsg": "**invalid ip xxx.xxx.xxx.xxx** ipv6 ::ffff:xxx.xxx.xxx.xxx, not in whitelist rid: 6280cf55-5sccscb42-7cscc91f0"

  1. 第一种情况:配置了错误的 appId 和 secret,这种情况也可能报这种错误
解决方案:修正 appId 和 secret 即可
  1. 第二种情况:该问题是由于微信公众需要调用方的IP在白名单中,才可以正常调用
    1. 解决方案:打开微信公众号,在【基础配置】中的 【IP白名单】中的配置报错的IP即可
    2. 注意事项:马上配置完,可能还会报同样的错误,这个时候是因为微信公众号更新没有实时的原因,可以稍微等一下再试试

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/11 5:31:05

Zynq PS 时钟子系统 3 种 PLL 功耗对比:Bypass 模式与动态关断策略

Zynq PS时钟子系统深度优化&#xff1a;三种PLL的能效分析与实战配置指南1. Zynq时钟架构核心解析Zynq-7000系列SoC的时钟子系统是其低功耗设计的神经中枢。处理系统(PS)通过三个可编程PLL——ARM PLL、DDR PLL和I/O PLL&#xff0c;为不同功能模块提供精准时钟信号。这些PLL并…

作者头像 李华
网站建设 2026/7/11 5:30:50

Unity AI寻路进阶:NavMeshModifier动态导航网格控制详解

1. 项目概述&#xff1a;为什么我们需要NavMeshModifier&#xff1f;在Unity里做AI寻路&#xff0c;NavMesh&#xff08;导航网格&#xff09;是绕不开的核心。我们通常的做法是&#xff0c;在场景里摆好静态的几何体&#xff0c;然后点击“Bake”&#xff08;烘焙&#xff09;…

作者头像 李华
网站建设 2026/7/11 5:30:26

AI智能体性能优化:内存管理与模型维护的工程实践

最近在开发AI应用时&#xff0c;你是不是也遇到过这样的问题&#xff1a;模型运行一段时间后响应变慢、输出质量下降&#xff0c;甚至出现莫名其妙的错误&#xff1f;很多人第一反应是检查代码逻辑或调整提示词&#xff0c;但往往忽略了最基础的因素——AI智能体也需要"补…

作者头像 李华
网站建设 2026/7/11 5:30:19

企业微信机器人开发指南:文本消息发送功能实现

在企业微信机器人开发过程中&#xff0c;文本消息发送是最基础也是最常用的功能之一。无论是客户通知、自动回复、销售跟进&#xff0c;还是群运营提醒&#xff0c;都需要通过消息发送接口完成信息触达。通过企业微信API开发&#xff0c;开发者可以调用消息发送接口&#xff0c…

作者头像 李华
网站建设 2026/7/11 5:29:57

P8772 [蓝桥杯 2022 省 A] 求和题解前缀和思路

题干 P8772 [蓝桥杯 2022 省 A] 求和 题目描述 给定 $n$ 个整数 $a_{1}, a_{2}, \cdots, a_{n}$, 求它们两两相乘再相加的和&#xff0c;即 $$ Sa_{1} \cdot a_{2}a_{1} \cdot a_{3}\cdotsa_{1} \cdot a_{n}a_{2} \cdot a_{3}\cdotsa_{n-2} \cdot a_{n-1}a_{n-2} \cdot a_{…

作者头像 李华
网站建设 2026/7/11 5:28:57

插件化开发:Android端的插件化与ArkUI-X的结合(131)

将 Android 端的插件化架构与 ArkUI-X 跨平台框架结合&#xff0c;是实现“一次开发&#xff0c;三端部署”&#xff08;HarmonyOS、Android、iOS&#xff09;以及复杂业务模块解耦的高级工程实践。在这种结合模式下&#xff0c;ArkUI-X 负责提供跨平台的 UI 渲染与业务逻辑&am…

作者头像 李华