一、问题基本信息
- 问题类型:小程序开发版调试异常
- 涉及功能:通过
generatescheme接口生成的开发版二维码,扫码后跳转空白页,开发者工具无日志输出 - 影响范围:本地开发环境无法调试分包内的签到功能(路径:
/signInPkg/pages/signIn/index)
二、问题现象描述
- 操作流程:
- ① 使用自研工具
QrcodeGenerator2调用微信generatescheme接口生成 URL Scheme,指定env_version=develop(开发版)、路径/signInPkg/pages/signIn/index及参数activityId=30; - ② 将 Scheme 编码为二维码图片,用手机微信(与开发者工具同账号)扫描(微信外扫码,非微信内直接识别);
- ③ 微信客户端跳转至小程序,但页面显示空白,无任何内容;
- ④ 微信开发者工具(已开启调试模式)无任何日志输出(Console 面板为空),状态栏未显示 “收到调试请求” 提示。
- 异常点:
- 开发版关联失败,未触发开发者工具调试;
- 无报错信息,无法定位空白页原因。
三、已执行的排查步骤
- 基础配置验证:
- 开发者工具与手机微信登录同一开发者账号(该账号为小程序管理员);
- 工具已开启「安全设置→允许通过二维码启动项目」;
- 小程序项目已正确加载,
app.json中分包配置正确(subpackages包含signInPkg,路径与代码一致); - 模拟器直接预览签到页(
/signInPkg/pages/signIn/index)可正常显示,无编译错误。
- 二维码参数验证:
- 解码二维码确认
openlink格式正确,包含path=/signInPkg/pages/signIn/index、query=activityId=30、env_version=develop; - 重新生成二维码(确保
access_token有效、请求体格式正确),问题复现。
- 接口调用验证:
generatescheme接口返回errcode=0,openlink格式为weixin://dl/business/?t=xxx;- 无接口调用频率超限提示(
errcode=45009),access_token获取正常(有效期 7200 秒)。
四、相关技术细节
- 小程序配置:
- AppID:
wxa8277f37d1cbd9c7 - 分包路径:
/signInPkg/pages/signIn/index(确认存在index.js、index.wxml等文件) - 开发者工具版本:1.06.2408010(最新稳定版)
2.URL Scheme 生成代码核心逻辑:
// 请求体构建(QrcodeGenerator2类)
JSONObject jumpWxa = new JSONObject();
jumpWxa.put("path", "/signInPkg/pages/signIn/index"); // 绝对路径
jumpWxa.put("query", "activityId=30");
jumpWxa.put("env_version", "develop"); // 指定开发版
JSONObject requestBody = new JSONObject();
requestBody.put("jump_wxa", jumpWxa);
requestBody.put("is_expire", false);
3.接口响应示例:
{
"errcode": 0,
"errmsg": "ok",
"openlink": "weixin://dl/business/?t=0Lvjen8jRrd"
}
五、诉求与疑问
- 为何
env_version=develop时,扫码未关联本地开发者工具(无请求提示、无日志)? - 空白页是否与
path路径格式、env_version参数传递有关? - 请提供开发版二维码关联失败的排查方向(如接口限制、参数校验规则等)。
六、附件说明
- 二维码生成工具完整代码(见上文
QrcodeGenerator2类); - 小程序分包配置截图、开发者工具安全设置截图(可补充提供)。
附录 小程序二维码生成方法代码
public static String generateActivityQrcode(String activityId, String miniProgramScheme) throws WriterException, IOException, WriterException {
if (activityId == null || activityId.trim().isEmpty()) {
throw new IllegalArgumentException("活动ID不能为空");
}
if (miniProgramScheme == null || !miniProgramScheme.startsWith("weixin://")) {
throw new IllegalArgumentException("URL Scheme格式错误,必须以\"weixin://\"开头");
}
String qrContent = miniProgramScheme;
String fileName = "activity_" + activityId + "_qrcode.png";
File saveDir = new File(SAVE_BASE_DIR);
if (!saveDir.exists() && !saveDir.mkdirs()) {
throw new IOException("无法创建二维码保存目录:" + SAVE_BASE_DIR);
}
File qrFile = new File(saveDir, fileName);
Path savePath = qrFile.toPath();
Map<EncodeHintType, Object> hints = new HashMap<>();
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
hints.put(EncodeHintType.MARGIN, 2);
QRCodeWriter qrWriter = new QRCodeWriter();
BitMatrix bitMatrix = qrWriter.encode(qrContent, BarcodeFormat.QR_CODE, QR_WIDTH, QR_HEIGHT, hints);
MatrixToImageWriter.writeToPath(bitMatrix, "PNG", savePath);
return savePath.toAbsolutePath().toString();
}
private static String getMiniProgramScheme(String activityId) throws IOException {
String accessToken = getAccessToken();
if (accessToken == null) {
throw new IOException("获取access_token失败,无法生成URL Scheme");
}
// 使用JSONObject构建请求体,确保格式正确
// JSONObject requestBody = new JSONObject();
// requestBody.put("path", SIGN_PAGE_PATH);
// requestBody.put("query", "activityId=" + activityId); // 将参数放在query字段中
// requestBody.put("is_expire", false);
// // 打印请求体以便调试
// System.out.println("微信接口请求体:" + requestBody.toString());
// 核心修改:path和query必须放在jump_wxa子对象中(微信强制规范)
JSONObject jumpWxa = new JSONObject();
jumpWxa.put("path", SIGN_PAGE_PATH); // 签到页面路径(不含参数)
jumpWxa.put("query", "activityId=" + activityId); // 活动ID参数
// 核心修改:添加env_version参数,指定为体验版(trial)
// 可选值:develop(开发版)、trial(体验版)、release(正式版)
// jumpWxa.put("env_version", "trial");
jumpWxa.put("env_version", "develop"); // 关键修改:指向本地开发版(开发者工具中的代码)
// 外层请求体(包含jump_wxa和is_expire)
JSONObject requestBody = new JSONObject();
requestBody.put("jump_wxa", jumpWxa); // 嵌套关键!
requestBody.put("is_expire", false); // 永久有效
// 打印请求体,确认格式正确(调试用)
System.out.println("微信接口请求体:" + requestBody.toString());
String schemeUrl = String.format(GET_SCHEME_URL, accessToken);
Request request = new Request.Builder()
.url(schemeUrl)
.addHeader("Content-Type", "application/json; charset=utf-8")
.post(RequestBody.create(
MediaType.parse("application/json; charset=utf-8"),
requestBody.toString()
))
.build();
try (Response response = OK_HTTP_CLIENT.newCall(request).execute()) {
if (!response.isSuccessful()) {
throw new IOException("调用微信Scheme接口失败,HTTP状态码:" + response.code());
}
String responseStr = response.body().string();
System.out.println("微信接口响应:" + responseStr); // 打印完整响应以便调试
JSONObject responseJson = new JSONObject(responseStr);
if (responseJson.has("errcode") && responseJson.getInt("errcode") != 0) {
String errMsg = responseJson.getString("errmsg");
throw new IOException("微信返回错误:errcode=" + responseJson.getInt("errcode") + ", errmsg=" + errMsg);
}
return responseJson.getString("openlink");
}
}

上图是二维码,下图是:微信扫码之后,弹出空白页面图
微信扫这个二维码,为什么没有触发本地环境微信开发者工具小程序代码?
在生成二维码是指向本地环境,jumpWxa.put("env_version", "develop"); // 关键修改:指向本地开发版(开发者工具中的代码)应用场景:
正在开发一个会议小程序,这个二维码是会议ID,以及小程序的签到URL生成的;
客户到场,微信扫码,二维码,触发小程序代码逻辑,调用服务端,处理签到逻辑。