鸿蒙5、6用户h5页面使用schemeURL跳转小程序失败

线上鸿蒙5、6用户h5页面使用schemeURL跳转小程序失败

情况描述

  • ios用户自动跳转成功
  • 安卓用户自动跳转成功
  • 测试机鸿蒙5、6跳转成功

客户经理提供用户手机截图:

线上用户自动跳转到网址为:weixin://dl/business/?t=xxx的网址了,没有拉起微信小程序

线上用户手机鸿蒙5、6跳转失败

复制代码

测试机鸿蒙5、6跳转成功获取到的useragent能够自动、点击按钮跳转

访问同事发现,称手机非纯血鸿蒙

vbnet 复制代码
userAgent: Mozilla/5.0(Phone;OpenHarmony 6.0; Android 10)AppleWebKit/537.36(KHTML,like Gecko) Chrome/132.0.0.0Safari/537.36 ArkWeb/6.0.0.120MobileHuaweiBrowser/5.1.11.312data"不
支持

问题原因

  1. 无法确认是纯血鸿蒙还是非纯血鸿蒙原因?
  2. 是浏览器问题?兼容性或者隐私设置问题?
  3. 如何区分纯血鸿蒙、非纯血鸿蒙?

以上问题,想和客户求证,还在等负责人推进...

关键代码

js 复制代码
// schemeURL密文地址
let url = 'weixin://dl/business/?t=xxx'  

window.onload = function () {  
setTimeout(() => {  
window.location.href = 'weixin://dl/business/?t=xxx';  
}, 500);

function jumpTo1(){  
window.location.href = url;  
}  
function jumpTo2(){  
const ifr = document.createElement('iframe');  
ifr.src = url;  
ifr.style.display = 'none';  
document.body.appendChild(ifr);  
// 可选:延时移除,避免影响  
setTimeout(() => {  
document.body.removeChild(ifr);  
}, 2000);  
}  
function jumpTo3(){  
const a = document.createElement('a');  
a.href = url;  
a.style.display = 'none';  
document.body.appendChild(a);  
a.click();  
// 可选:延时移除,避免影响  
setTimeout(() => {  
document.body.removeChild(a);  
}, 2000);  
}

源代码

jsp页面

jsp 复制代码
<div class="container" id="arcode">  
<div class="note">  
<strong>温馨提示:</strong>此功能需要在微信外浏览器打开,如手机自带浏览器、Safari或Chrome等。  
</div>  
  
<%-- <button class="jump-btn" onclick="loadScheme('develop')">密文开发版本</button>--%>  
<%-- <button class="jump-btn" onclick="loadMWScheme()">明文跳转小程序</button>--%>  
<div>  
<button id="hmbtn" class="jump-btn" onclick="joinWhiteList()" style="display:none"> 进入小程序</button>  
<button id="fhmbtn2" class="jump-btn" onclick="loadScheme()" style="display:none"> 进入小程序</button>  
<button id="hmbtn2" class="jump-btn" onclick="joinWhiteList()" style="display:none"> 上报设备信息</button>  
</div>  
<p id="device3" style="color: red"></p>  
<p id="device"></p>  
<div class="steps">  
<p><strong>跳转说明:</strong></p>  
<ul>  
<li>确保您已安装最新版本的微信App</li>  
</ul>  
</div>  
  
<div class="qr-code">  
<div class="qr-placeholder" v-loading="loading">  
<view id="mini"></view>  
</div>  
<p>如有问题,请联系客服支持</p>  
</div>  
  
</div>  
  
<script>  
new Vue({  
el: '#arcode',  
data() {  
return {  
loading: false,  
};  
},  
});  
  
const baseURL = "<%=basePath%>"  
const service = axios.create({  
baseURL: baseURL,  
timeout: 15000,  
withCredentials: true,  
})  
  
service.interceptors.request.use(config => {  
if (config.method === 'get') {  
if (config.params) {  
config.params['date'] = new Date().getTime()  
} else {  
config.url = config.url + `?date=` + new Date().getTime()  
}  
}  
return config  
}, error => {  
ELEMENT.Message({  
message: '错误信息:' + error,  
type: 'warning'  
});  
return Promise.reject(error)  
})  
  
service.interceptors.response.use(resData => {  
if (resData.headers['content-disposition']) {  
resData.data.contentDisposition = resData.headers['content-disposition']  
}  
if (resData.status >= 200 && resData.status < 300) {  
const {code, result, msg} = resData.data  
if (code === 1) {  
return result  
} else if (code === 10012) {  
ELEMENT.Message({  
message: 'token已过期,请您重新登录!',  
type: 'warning'  
});  
setTimeout(() => location.reload(), 1500);  
return Promise.reject(code)  
} else {  
if (msg == undefined) {  
return resData  
}  
ELEMENT.Message({  
message: msg,  
type: 'warning'  
});  
return Promise.reject(code)  
}  
}  
}, error => {  
ELEMENT.Message({  
message: '错误信息:' + error,  
type: 'warning'  
});  
return Promise.reject(error)  
})  
  
function GetWxMiniScheme(code, ticket, version) {  
return service({  
method: 'GET',  
url: '/api/scheme/getWxMiniScheme/' + code + '/' + ticket + '/' + version,  
})  
}  
  
function AddWhitelist(ticket, model) {  
return service({  
method: 'GET',  
url: '/api/scheme/addWhitelist/' + ticket + '/' + model,  
})  
}  
  
var ticket = `${ticket}`;  
const paramscom = new URLSearchParams(window.location.search);  
ticket = paramscom.get('ticket');  
// 系统  
let ua = navigator.userAgent.toLowerCase();  
let isHo = false  
  
// 1. 识别鸿蒙系(优先级最高,避免被安卓识别覆盖)  
const isOpenHarmony = /openharmony\s?([0-9._]+)/i.test(ua) || /openharmony\/([0-9._]+)/i.test(ua);  
const openHarmonyVersion = (ua.match(/openharmony\s?([0-9._]+)/i) || ua.match(/openharmony\/([0-9._]+)/i) || [])[1] || '';  
  
const isHarmonyOS = /harmonyos\s?([0-9._]+)/i.test(ua) || /harmonyos\/([0-9._]+)/i.test(ua);  
const harmonyOSVersion = (ua.match(/harmonyos\s?([0-9._]+)/i) || ua.match(/harmonyos\/([0-9._]+)/i) || [])[1] || '';  
  
// 2. 识别iOS(包含iPhone/iPad/iPod)  
const isIOS = /iphone|ipad|ipod|ios/i.test(ua);  
const iosVersion = (ua.match(/os\s+(\d+[._]\d+)/i) || [])[1]?.replace('_', '.') || '';  
  
// 3. 识别安卓  
const isAndroid = /android|adr/i.test(ua) && !isOpenHarmony && !isHarmonyOS; // 排除鸿蒙(鸿蒙UA含android)  
const androidVersion = (ua.match(/android\s+(\d+[._]\d+)/i) || [])[1]?.replace('_', '.') || '';  
  
// 4. 识别Windows Phone  
const isWindowsPhone = /windows phone|wp/i.test(ua);  
const wpVersion = (ua.match(/windows phone\s+(\d+[._]\d+)/i) || [])[1]?.replace('_', '.') || '';  
  
// 5. 识别其他系统(Linux/MacOS/Windows)  
const isLinux = /linux/i.test(ua) && !isAndroid && !isOpenHarmony && !isHarmonyOS;  
const isMacOS = /mac os x/i.test(ua);  
const isWindows = /windows|win32/i.test(ua);  
  
// 6. 最终系统类型和版本赋值(无Unknown)  
let systemType = '';  
let systemVersion = '';  
  
if (isOpenHarmony) {  
systemType = 'OpenHarmony';  
systemVersion = openHarmonyVersion;  
isHo = true  
} else if (isHarmonyOS) {  
systemType = 'HarmonyOS';  
systemVersion = harmonyOSVersion;  
isHo = true  
} else if (isIOS) {  
systemType = 'iOS';  
systemVersion = iosVersion;  
} else if (isAndroid) {  
systemType = 'Android';  
systemVersion = androidVersion;  
} else if (isWindowsPhone) {  
systemType = 'Windows Phone';  
systemVersion = wpVersion;  
} else if (isLinux) {  
systemType = 'Linux';  
systemVersion = '';  
} else if (isMacOS) {  
systemType = 'MacOS';  
systemVersion = (ua.match(/mac os x\s+(\d+[._]\d+)/i) || [])[1]?.replace('_', '.') || '';  
} else if (isWindows) {  
systemType = 'Windows';  
systemVersion = (ua.match(/windows nt\s+(\d+[._]\d+)/i) || [])[1]?.replace('_', '.') || '';  
} else {  
// 兜底:仍识别不出则显示「Other」而非Unknown  
systemType = 'Other';  
systemVersion = '';  
}  
// 打印最终结果(无Unknown)  
console.log('系统类型:', systemType, '版本号:', systemVersion);  
const deviceInfo = {  
systemType,  
systemVersion,  
userAgent: navigator.userAgent,  
platform: navigator.platform,  
time: new Date().toISOString()  
};  
const p = document.querySelector('#device');  
const p3 = document.querySelector('#device3');  
p.style.whiteSpace = 'pre-wrap';  
p.innerText = '系统类型:' + deviceInfo.systemType + '\n' + '版本号:' + deviceInfo.systemVersion + '\n平台:' + deviceInfo.platform + '\n' + 'UserAgent: ' + deviceInfo.userAgent + 'data"' + (navigator.userAgentData ? JSON.stringify(navigator.userAgentData) : '不支持');  
  
  
// 页面加载后延迟执行跳转  
window.onload = function () {  
if (isHo) {  
document.getElementById('hmbtn').style.display = 'block';  
document.getElementById('hmtext').style.display = 'block';  
} else {  
// 非鸿蒙系统自动跳转-显示上报信息按钮(加白名单)  
setTimeout(() => {  
loadScheme()  
}, 500);  
}  
  
  
};  
  
// 【核心】全浏览器适配的清理逻辑(含夸克/华为)  
function clearH5PageAfterJump() {  
// 第一步:识别浏览器类型  
const ua = navigator.userAgent.toLowerCase();  
const browserType = {  
isHuawei: ua.includes('huaweibrowser') || ua.includes('harmony') || ua.includes('huawei'),  
isQuark: ua.includes('quark') || ua.includes('quarkmini'),  
isChrome: ua.includes('chrome') && !ua.includes('mobile safari'),  
isSafari: ua.includes('mobile safari') && !ua.includes('chrome'),  
isOther: true  
};  
// 修正other判断  
browserType.isOther = !browserType.isHuawei && !browserType.isQuark && !browserType.isChrome && !browserType.isSafari;  
  
try {  
// 1. 华为浏览器:优先调用专属API  
if (browserType.isHuawei && window.HuaweiBrowser) {  
window.HuaweiBrowser.closeCurrentTab();  
}  
// 2. 通用关闭尝试(仅部分浏览器生效)  
else if (window.close) {  
window.close();  
setTimeout(() => window.close(), 200);  
}  
} catch (e) {  
console.log('自动关闭失败,执行强制清空', e);  
  
// 第二步:分浏览器强制清空(核心适配夸克)  
if (browserType.isQuark) {  
// 夸克专属:深度清空+重写页面结构  
document.open(); // 打开文档流,清空缓存  
document.write('<html class="blank-page"><body class="blank-page"></body></html>');  
document.close(); // 关闭文档流,强制渲染  
// 替换历史记录+禁止返回  
window.location.replace('about:blank');  
// 禁用所有交互  
document.body.style.pointerEvents = 'none';  
// 终止所有异步任务  
for (let i = 0; i < 2000; i++) {  
clearInterval(i);  
clearTimeout(i);  
}  
// 夸克特殊:延迟再次清空  
setTimeout(() => {  
document.body.innerHTML = '';  
document.documentElement.className = 'blank-page';  
}, 100);  
}  
// 华为浏览器兜底  
else if (browserType.isHuawei) {  
document.documentElement.innerHTML = '';  
document.body.innerHTML = '';  
window.location.replace('about:blank');  
document.documentElement.style.display = 'none';  
document.body.style.display = 'none';  
for (let i = 0; i < 1000; i++) {  
clearInterval(i);  
clearTimeout(i);  
}  
}  
// 其他浏览器通用方案  
else {  
document.body.innerHTML = '';  
window.location.replace('about:blank');  
document.documentElement.className = 'blank-page';  
}  
}  
}  
  
// 监听页面隐藏(跳转成功),执行清理  
document.addEventListener('visibilitychange', function () {  
if (document.hidden) {  
console.log('页面隐藏 → 跳转成功,清理H5页面');  
// 不同浏览器延迟适配  
const ua = navigator.userAgent.toLowerCase();  
let delay = 500; // 默认  
if (ua.includes('huawei')) delay = 300; // 华为  
if (ua.includes('quark')) delay = 200; // 夸克(更快响应)  
  
setTimeout(() => {  
clearH5PageAfterJump();  
}, delay);  
}  
});  
  
// 所有系统统一走a标签跳转  
function jumpByATag(url) {  
const ua = navigator.userAgent.toLowerCase();  
const isAndroid = ua.indexOf('android') > -1 || ua.indexOf('adr') > -1;  
const isIOS = !!ua.match(/\(i[^;]+;( u;)? cpu.+mac os x/);  
const isXiaomi = ua.indexOf('mi ') > -1 || ua.indexOf('xiaomi') > -1 ||  
ua.indexOf('redmi') > -1;  
  
if (isIOS) {  
window.location.href = url;  
} else if (isAndroid || isXiaomi) {  
// 安卓(尤其是⼩⽶)⽤iframe中转  
const ifr = document.createElement('iframe');  
ifr.src = url;  
ifr.style.display = 'none';  
document.body.appendChild(ifr);  
// 可选:延时移除,避免影响  
setTimeout(() => {  
document.body.removeChild(ifr);  
}, 2000);  
} else {  
const a = document.createElement('a');  
a.href = url;  
a.style.display = 'none';  
document.body.appendChild(a);  
a.click();  
// 可选:延时移除,避免影响  
setTimeout(() => {  
document.body.removeChild(a);  
}, 2000);  
}  
}  
  
function loadMWScheme() {  
var appid = "wx5728ecf19f0d9405";  
var path = "pages/index/index";  
var env = "develop";  
let code1 = `${code}`;  
  
const params = new URLSearchParams(window.location.search);  
ticket = params.get('ticket');  
let queryObj = 'source=h5&ticket=' + ticket + '&code=' + code1;  
let query = encodeURIComponent(queryObj);  
let finalUrl = 'weixin://dl/business/?appid=' + appid + '&path=' + path + '&query=' + query + '&env_version=' + env;  
console.log(finalUrl + '明文跳转');  
jumpByATag(finalUrl);  
}  
  
function loadScheme(version = 'release') {  
try {  
let code1 = `${code}`;  
const params = new URLSearchParams(window.location.search);  
ticket = params.get('ticket');  
// 鸿蒙系统直接加入白名单  
  
// 否则-  
GetWxMiniScheme(code1, ticket, version).then(res => {  
const schemeUrl = res.urlScheme;  
let jumped = false;  
let hasReported = false;  
const start = Date.now();  
  
const handleVisibility = () => {  
if (document.hidden) {  
jumped = true;  
console.log('页面隐藏 → 推测跳转成功');  
document.removeEventListener('visibilitychange', handleVisibility);  
clearH5PageAfterJump();  
}  
};  
document.addEventListener('visibilitychange', handleVisibility);  
  
const interval = setInterval(() => {  
const elapsed = Date.now() - start;  
if (jumped || hasReported || elapsed > 8000) {  
clearInterval(interval);  
return;  
}  
if (elapsed >= 5000 && !jumped) {  
console.log('检测 5 秒未跳转,开始上报');  
hasReported = true;  
reportDeviceInfo(ticket);  
clearInterval(interval);  
}  
}, 1000);  
  
// 统一拼接跳转URL 0为明文跳转  
let finalJumpUrl = '';  
if (res.status == 0) {  
var appid = "wx5728ecf19f0d9405";  
var path = "pages/index/index";  
var env = version;  
let queryObj = 'source=h5&ticket=' + ticket + '&code=' + code1;  
let query = encodeURIComponent(queryObj);  
finalJumpUrl = 'weixin://dl/business/?appid=' + appid + '&path=' + path + '&query=' + query + '&env_version=' + env;  
console.log(finalJumpUrl + '明文跳转', res);  
} else {  
finalJumpUrl = schemeUrl;  
console.log(schemeUrl + ' 密文跳转', res);  
}  
  
// 所有系统统一走a标签跳转  
jumpByATag(finalJumpUrl);  
  
}).catch(err => {  
console.error('获取Scheme失败:', err);  
});  
} catch (err) {  
console.error('loadScheme异常:', err);  
}  
}  
  
function reportDeviceInfo(ticket1 = ticket) {  
console.log(navigator.userAgent, navigator, 'navigator', ticket1)  
if (!isHo) {  
p3.innerText = '非鸿蒙系统,请从App跳转小程序'  
p.innerText = '系统类型:' + deviceInfo.systemType + '\n' + '版本号:' + deviceInfo.systemVersion + '\n平台:' + deviceInfo.platform + '\n' + 'UserAgent: ' + deviceInfo.userAgent + 'data"' + navigator.userAgentData;  
console.log('检测设备信息:', deviceInfo, navigator.userAgentData, 'userAgentData', systemType);  
ELEMENT.Message({  
message: '请点击进入小程序,失败可选择上报设备信息,从小程序进入',  
type: 'warning'  
});  
document.getElementById('hmbtn2').style.display = 'block';  
document.getElementById('fhmbtn2').style.display = 'block';  
return  
}  
AddWhitelist(ticket1, systemType + systemVersion).then(res => {  
if (res == '')  
res = '已经加入白名单,请从访客小程序入口进入'  
ELEMENT.Message({  
message: res,  
type: 'error'  
});  
}).catch(err => {  
console.log(err, 'err')  
})  
}  
  
function joinWhiteList() {  
let ticket1 = ticket  
AddWhitelist(ticket1, systemType + systemVersion).then(res => {  
if (res == '')  
res = '已经加入白名单,请从访客小程序入口进入'  
ELEMENT.Message({  
message: res,  
type: 'error'  
});  
}).catch(err => {  
console.log(err, 'err')  
})  
}  
</script>
相关推荐
醉城夜风~27 分钟前
CSS元素显示模式(display)
前端·css
AI大模型-小华1 小时前
Codex 三方充值快速入门指南
java·前端·数据库·chatgpt·ai编程·codex·chatgpt pro
做前端的娜娜子3 小时前
同一链接实现 PC Web 与移动 H5 自适应
前端·掘金·金石计划
小帅不太帅4 小时前
架构没变、规模没变,DeepSeek V4 Flash 正式版凭什么暴涨 47 分?
前端·aigc·deepseek
jarvisuni4 小时前
DeepSeekFlash前端依旧拉垮,而且变慢了很多!
前端·javascript·算法
卷福同学5 小时前
AI编程出海第二步:验证关键词能否做站
前端·人工智能·后端
赵庆明老师6 小时前
Vben精讲:21-详解web-antd:tsconfig.json
前端·json·vim
wc886 小时前
微软EDGE浏览器功能学习
前端·学习·edge
Csvn6 小时前
🎯 原生 `<dialog>` 元素:终于可以扔掉一半的自定义弹窗组件了?
前端