fix(weixin-sdk): fix iOS scanQRCode false camera permission error
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,16 +1,14 @@
|
||||
import type { WechatJssdkConfig } from '@dukang/shared-types';
|
||||
import { isIosDevice, isWechatBrowser, isWechatDevTools } from './env';
|
||||
import { DEFAULT_JS_API_LIST } from './types';
|
||||
|
||||
const JSSDK_URL = 'https://res.wx.qq.com/open/js/jweixin-1.6.0.js';
|
||||
const IOS_ENTRY_URL_KEY = 'dukang_wx_ios_entry_url';
|
||||
|
||||
let scriptPromise: Promise<void> | null = null;
|
||||
let configured = false;
|
||||
let configuredUrl: string | null = null;
|
||||
|
||||
function currentPageUrl() {
|
||||
return typeof window !== 'undefined' ? normalizeJssdkPageUrl(window.location.href) : '';
|
||||
}
|
||||
|
||||
/** 参与 JSSDK 签名的页面 URL(去掉 hash、OAuth 回跳参数) */
|
||||
export function normalizeJssdkPageUrl(rawUrl: string): string {
|
||||
try {
|
||||
@@ -25,6 +23,33 @@ export function normalizeJssdkPageUrl(rawUrl: string): string {
|
||||
}
|
||||
}
|
||||
|
||||
/** iOS 微信内 SPA:签名 URL 须用首次进入页面的入口 URL,而非路由跳转后的当前 URL */
|
||||
export function captureIosJssdkEntryUrl(): void {
|
||||
if (typeof window === 'undefined') return;
|
||||
if (!isIosDevice() || !isWechatBrowser() || isWechatDevTools()) return;
|
||||
if (sessionStorage.getItem(IOS_ENTRY_URL_KEY)) return;
|
||||
sessionStorage.setItem(IOS_ENTRY_URL_KEY, normalizeJssdkPageUrl(window.location.href));
|
||||
}
|
||||
|
||||
/** 获取参与 JSSDK 签名的 URL */
|
||||
export function getJssdkSignUrl(rawUrl?: string): string {
|
||||
const current = normalizeJssdkPageUrl(rawUrl ?? (typeof window !== 'undefined' ? window.location.href : ''));
|
||||
if (typeof window !== 'undefined' && isIosDevice() && isWechatBrowser() && !isWechatDevTools()) {
|
||||
const entry = sessionStorage.getItem(IOS_ENTRY_URL_KEY);
|
||||
if (entry) return entry;
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
function isJssdkDebugEnabled(): boolean {
|
||||
if (typeof window === 'undefined') return false;
|
||||
try {
|
||||
return new URLSearchParams(window.location.search).get('wxdebug') === '1';
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function stripOAuthParamsFromLocation(): void {
|
||||
if (typeof window === 'undefined') return;
|
||||
const url = new URL(window.location.href);
|
||||
@@ -77,8 +102,9 @@ export async function initWechatJssdk(options: {
|
||||
getAccessToken?: () => string | null;
|
||||
jsApiList?: string[];
|
||||
}): Promise<void> {
|
||||
captureIosJssdkEntryUrl();
|
||||
const { apiBase, clientApp, getAccessToken } = options;
|
||||
const pageUrl = options.url ?? currentPageUrl();
|
||||
const pageUrl = options.url ?? getJssdkSignUrl();
|
||||
await loadScript();
|
||||
if (!window.wx) throw new Error('微信 JSSDK 不可用');
|
||||
|
||||
@@ -92,7 +118,7 @@ export async function initWechatJssdk(options: {
|
||||
window.wx!.config({
|
||||
...config,
|
||||
jsApiList,
|
||||
debug: false,
|
||||
debug: isJssdkDebugEnabled(),
|
||||
});
|
||||
window.wx!.ready(() => {
|
||||
configured = true;
|
||||
@@ -104,7 +130,8 @@ export async function initWechatJssdk(options: {
|
||||
}
|
||||
|
||||
export function isJssdkReady(): boolean {
|
||||
return configured && !!window.wx && configuredUrl === currentPageUrl();
|
||||
const signUrl = getJssdkSignUrl();
|
||||
return configured && !!window.wx && configuredUrl === signUrl;
|
||||
}
|
||||
|
||||
export async function ensureJssdkReady(options: {
|
||||
@@ -114,8 +141,13 @@ export async function ensureJssdkReady(options: {
|
||||
getAccessToken?: () => string | null;
|
||||
jsApiList?: string[];
|
||||
}): Promise<void> {
|
||||
const pageUrl = options.url ?? currentPageUrl();
|
||||
captureIosJssdkEntryUrl();
|
||||
const pageUrl = options.url ?? getJssdkSignUrl();
|
||||
if (!isJssdkReady()) {
|
||||
await initWechatJssdk({ ...options, url: pageUrl });
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
captureIosJssdkEntryUrl();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user