|
|
@@ -1154,8 +1154,17 @@
|
|
|
var wxLaunchAppIdCache = '';
|
|
|
var wxLaunchMounted = false;
|
|
|
var wxPreparePromise = null;
|
|
|
+ var wxPrepareState = 'idle';
|
|
|
var wxTagReadyWaiters = [];
|
|
|
|
|
|
+ function wxPrepareReject(step, err) {
|
|
|
+ var base = err instanceof Error ? err.message : String(err || '');
|
|
|
+ var e = new Error('[' + step + '] ' + base);
|
|
|
+ e.wxStep = step;
|
|
|
+ e.cause = err;
|
|
|
+ return e;
|
|
|
+ }
|
|
|
+
|
|
|
function notifyWxTagReady() {
|
|
|
wxTagReady = true;
|
|
|
var list = wxTagReadyWaiters.slice();
|
|
|
@@ -1169,20 +1178,15 @@
|
|
|
|
|
|
function waitForWxTagReady(timeoutMs) {
|
|
|
if (wxTagReady) return Promise.resolve();
|
|
|
- return new Promise(function (resolve, reject) {
|
|
|
- var done = false;
|
|
|
- function finish(ok) {
|
|
|
- if (done) return;
|
|
|
- done = true;
|
|
|
- if (ok) resolve();
|
|
|
- else reject(new Error('微信开放标签初始化超时'));
|
|
|
- }
|
|
|
- wxTagReadyWaiters.push(function () {
|
|
|
- finish(true);
|
|
|
- });
|
|
|
+ if (!wxLaunchMounted) {
|
|
|
+ return Promise.reject(wxPrepareReject('tagMount', new Error('开放标签未挂载')));
|
|
|
+ }
|
|
|
+ return new Promise(function (resolve) {
|
|
|
+ wxTagReadyWaiters.push(resolve);
|
|
|
window.setTimeout(function () {
|
|
|
- finish(wxTagReady);
|
|
|
- }, timeoutMs || 8000);
|
|
|
+ if (!wxTagReady) notifyWxTagReady();
|
|
|
+ resolve();
|
|
|
+ }, timeoutMs || 2500);
|
|
|
});
|
|
|
}
|
|
|
|
|
|
@@ -1252,12 +1256,14 @@
|
|
|
function fetchWxConfig() {
|
|
|
var pageUrl = getWxSignPageUrl();
|
|
|
var apiUrl = WX_CONFIG_API + '?url=' + encodeURIComponent(pageUrl);
|
|
|
+ console.log('[wx-prepare] getWxConfig url=', pageUrl);
|
|
|
return fetch(apiUrl, {
|
|
|
method: 'GET',
|
|
|
mode: 'cors',
|
|
|
credentials: 'omit',
|
|
|
headers: { Accept: 'application/json' }
|
|
|
}).then(function (res) {
|
|
|
+ alert(res)
|
|
|
if (!res.ok) throw new Error('HTTP ' + res.status);
|
|
|
return res.json();
|
|
|
});
|
|
|
@@ -1399,69 +1405,112 @@
|
|
|
|
|
|
/** 公众号内:先 GET getWxConfig,再 wx.config + 开放标签唤起 App */
|
|
|
function prepareWeChatAppLaunch(forceRefresh) {
|
|
|
- if (!forceRefresh && wxPreparePromise) return wxPreparePromise;
|
|
|
+ if (!forceRefresh && wxPreparePromise && wxPrepareState === 'pending') {
|
|
|
+ return wxPreparePromise;
|
|
|
+ }
|
|
|
+ if (
|
|
|
+ !forceRefresh &&
|
|
|
+ wxPrepareState === 'ok' &&
|
|
|
+ wxLaunchMounted &&
|
|
|
+ wxConfigReady &&
|
|
|
+ wxTagReady
|
|
|
+ ) {
|
|
|
+ return Promise.resolve();
|
|
|
+ }
|
|
|
if (forceRefresh) {
|
|
|
wxPreparePromise = null;
|
|
|
wxConfigReady = false;
|
|
|
wxTagReady = false;
|
|
|
wxLaunchMounted = false;
|
|
|
+ wxPrepareState = 'idle';
|
|
|
}
|
|
|
setOpenAppWeChatPending(true);
|
|
|
+ wxPrepareState = 'pending';
|
|
|
wxPreparePromise = loadWxJssdk()
|
|
|
+ .catch(function (e) {
|
|
|
+ throw wxPrepareReject('jssdk', e);
|
|
|
+ })
|
|
|
.then(function () {
|
|
|
return fetchWxConfig();
|
|
|
})
|
|
|
+ .catch(function (e) {
|
|
|
+ throw wxPrepareReject('fetch', e);
|
|
|
+ })
|
|
|
.then(function (res) {
|
|
|
var cfg = normalizeWxConfigPayload(res);
|
|
|
- if (!cfg) throw new Error('getWxConfig 返回无效');
|
|
|
+ if (!cfg) throw wxPrepareReject('normalize', new Error('getWxConfig 返回无效'));
|
|
|
if (wxConfigReady && cfg.launchAppId && wxLaunchAppIdCache === cfg.launchAppId) {
|
|
|
return cfg;
|
|
|
}
|
|
|
wxConfigReady = false;
|
|
|
return applyWxConfig(cfg);
|
|
|
})
|
|
|
+ .catch(function (e) {
|
|
|
+ if (e && e.wxStep) throw e;
|
|
|
+ throw wxPrepareReject('wxConfig', e);
|
|
|
+ })
|
|
|
.then(function (cfg) {
|
|
|
var launchId =
|
|
|
(cfg && cfg.launchAppId) || wxLaunchAppIdCache || WX_LAUNCH_APP_ID || '';
|
|
|
- if (!launchId) throw new Error('缺少移动应用 AppId');
|
|
|
+ if (!launchId) throw wxPrepareReject('launchAppId', new Error('缺少移动应用 AppId'));
|
|
|
if (!mountWxOpenLaunchApp(launchId)) {
|
|
|
- throw new Error('微信开放标签挂载失败');
|
|
|
+ throw wxPrepareReject('tagMount', new Error('微信开放标签挂载失败'));
|
|
|
}
|
|
|
- return waitForWxTagReady(8000).then(function () {
|
|
|
+ return waitForWxTagReady(2500).then(function () {
|
|
|
return cfg;
|
|
|
});
|
|
|
})
|
|
|
+ .catch(function (e) {
|
|
|
+ if (e && e.wxStep) throw e;
|
|
|
+ throw wxPrepareReject('tagReady', e);
|
|
|
+ })
|
|
|
.then(function (cfg) {
|
|
|
+ wxPrepareState = 'ok';
|
|
|
setOpenAppWeChatPending(false);
|
|
|
+ console.log('[wx-prepare] ok', {
|
|
|
+ wxConfigReady: wxConfigReady,
|
|
|
+ wxTagReady: wxTagReady,
|
|
|
+ wxLaunchMounted: wxLaunchMounted
|
|
|
+ });
|
|
|
return cfg;
|
|
|
})
|
|
|
.catch(function (e) {
|
|
|
+ wxPrepareState = 'fail';
|
|
|
+ wxPreparePromise = null;
|
|
|
setOpenAppWeChatPending(false);
|
|
|
+ console.warn('[wx-prepare] fail', e && e.wxStep, e && e.message);
|
|
|
throw e;
|
|
|
});
|
|
|
return wxPreparePromise;
|
|
|
}
|
|
|
|
|
|
function showWeChatLaunchError(e) {
|
|
|
- console.warn('[微信唤起App]', e, {
|
|
|
+ var step = (e && e.wxStep) || '';
|
|
|
+ console.warn('[微信唤起App]', step, e, {
|
|
|
signUrl: getWxSignPageUrl(),
|
|
|
+ wxPrepareState: wxPrepareState,
|
|
|
wxConfigReady: wxConfigReady,
|
|
|
wxLaunchMounted: wxLaunchMounted,
|
|
|
wxTagReady: wxTagReady
|
|
|
});
|
|
|
var msg = '暂时无法打开 App';
|
|
|
- if (e && e.message) {
|
|
|
- if (/HTTP 404/i.test(e.message)) {
|
|
|
- msg = '微信配置接口 404,请确认接口为 /alienStore/wx/getWxConfig';
|
|
|
- } else if (/缺少移动应用/i.test(e.message)) {
|
|
|
- msg = '缺少移动应用 AppId,请配置 WX_LAUNCH_APP_ID';
|
|
|
- } else if (/getWxConfig 返回无效/i.test(e.message)) {
|
|
|
- msg = 'getWxConfig 数据无效,请查看控制台 [getWxConfig]';
|
|
|
- } else if (/wx\.config|签名/i.test(e.message)) {
|
|
|
- msg = '微信签名失败:页面域名须与 JS 安全域名一致(' + getWxSignPageUrl() + ')';
|
|
|
- } else if (/挂载失败|初始化超时/i.test(e.message)) {
|
|
|
- msg = '开放标签未就绪,请刷新页面后重试';
|
|
|
- }
|
|
|
+ var raw = (e && e.message) || '';
|
|
|
+ if (step === 'fetch' && /HTTP 404/i.test(raw)) {
|
|
|
+ msg = '微信配置接口 404,请确认接口为 /alienStore/wx/getWxConfig';
|
|
|
+ } else if (step === 'normalize') {
|
|
|
+ msg = 'getWxConfig 数据无效,请查看控制台 [getWxConfig]';
|
|
|
+ } else if (step === 'launchAppId') {
|
|
|
+ msg = '缺少移动应用 AppId,请配置 WX_LAUNCH_APP_ID';
|
|
|
+ } else if (step === 'wxConfig' || /wx\.config|签名|invalid signature/i.test(raw)) {
|
|
|
+ msg =
|
|
|
+ '微信签名失败:传给接口的 url 须与当前页完全一致\n' +
|
|
|
+ getWxSignPageUrl();
|
|
|
+ } else if (step === 'tagMount' || step === 'tagReady') {
|
|
|
+ msg = '开放标签未就绪,请刷新页面后重试';
|
|
|
+ } else if (step === 'jssdk') {
|
|
|
+ msg = '微信 JS-SDK 加载失败,请检查网络';
|
|
|
+ } else if (/HTTP 404/i.test(raw)) {
|
|
|
+ msg = '微信配置接口 404';
|
|
|
}
|
|
|
showWxLaunchTip(msg);
|
|
|
}
|
|
|
@@ -1473,12 +1522,19 @@
|
|
|
return;
|
|
|
}
|
|
|
setOpenAppWeChatPending(true);
|
|
|
- var chain = wxPreparePromise || prepareWeChatAppLaunch(false);
|
|
|
+ var chain;
|
|
|
+ if (wxPrepareState === 'fail' || !wxPreparePromise) {
|
|
|
+ chain = prepareWeChatAppLaunch(true);
|
|
|
+ } else {
|
|
|
+ chain = wxPreparePromise;
|
|
|
+ }
|
|
|
chain
|
|
|
.then(function () {
|
|
|
setOpenAppWeChatPending(false);
|
|
|
if (wxTagReady) {
|
|
|
tryClickWxLaunchButton();
|
|
|
+ } else {
|
|
|
+ showWxLaunchTip('开放标签未就绪,请再点一次按钮');
|
|
|
}
|
|
|
})
|
|
|
.catch(function (e) {
|
|
|
@@ -2771,7 +2827,9 @@
|
|
|
function initWeChatAppLaunchEarly() {
|
|
|
if (!isWeChatInAppBrowser()) return;
|
|
|
prepareWeChatAppLaunch(false).catch(function (e) {
|
|
|
- console.warn('[微信预加载 getWxConfig]', e);
|
|
|
+ console.warn('[微信预加载]', e && e.wxStep, e && e.message);
|
|
|
+ wxPreparePromise = null;
|
|
|
+ wxPrepareState = 'fail';
|
|
|
setOpenAppWeChatPending(false);
|
|
|
});
|
|
|
}
|