From 33a3c48272eb5b0f57e952a539916db7a244bd02 Mon Sep 17 00:00:00 2001
From: hejianhao <15708179461@qq.com>
Date: 星期五, 21 八月 2026 10:21:16 +0800
Subject: [PATCH] feat0806: 退出直播间不清理缓存
---
traditionalApp/pages/webview/webview.vue | 133 ---------------------
traditionalApp/pages/settings/settings.vue | 92 +-------------
traditionalApp/utils/webview-cache.js | 128 +++++++++++++++++++++
3 files changed, 142 insertions(+), 211 deletions(-)
diff --git a/traditionalApp/pages/settings/settings.vue b/traditionalApp/pages/settings/settings.vue
index 2f08a09..0a19e9d 100644
--- a/traditionalApp/pages/settings/settings.vue
+++ b/traditionalApp/pages/settings/settings.vue
@@ -96,6 +96,7 @@
import { bindSettingsWechat, cancelSettingsAccount, getSettingsProfile, logoutSettingsAccount } from './service.js'
import { cacheSettingsProfile, clearSettingsLoginSession, isSuccessResponse, maskPhone, normalizeSettingsProfile } from './utils.js'
import { normalizeOptionalText } from '@/utils/utils.js'
+import { clearWebViewData } from '@/utils/webview-cache.js'
interface WechatLoginResult {
code?: string
@@ -291,105 +292,34 @@
}
/**
- * 清除 WebView 缓存和 localStorage。
+ * 退出登录时清除本地存储与 WebView 缓存。
+ * WebView 部分复用进入直播间前的彻底清理逻辑(含原生 Cookie/存储 API),保证登录态不残留。
*/
function clearWebViewCache() {
- console.log('[clearWebViewCache] 函数被调用')
-
- let logMessages = []
- logMessages.push('开始清除缓存')
-
try {
// 清除 uni.storage(所有环境通用)
try {
uni.clearStorageSync()
- console.log('[clearWebViewCache] uni.storage 已清除')
- logMessages.push('uni.storage 已清除')
} catch (e) {
console.error('[clearWebViewCache] 清除 uni.storage 失败:', e)
- logMessages.push('uni.storage 清除失败')
}
// #ifdef APP-PLUS
- console.log('[clearWebViewCache] APP-PLUS 环境,开始清除 WebView 缓存')
- logMessages.push('APP-PLUS 环境检测到')
-
// 清除 plus.storage
- if (plus.storage) {
- plus.storage.clear()
- console.log('[clearWebViewCache] plus.storage 已清除')
- logMessages.push('plus.storage 已清除')
- }
-
- // 清除 WebView 缓存
- const currentWebview = plus.webview.currentWebview()
- if (currentWebview && typeof currentWebview.clearCache === 'function') {
- currentWebview.clearCache()
- console.log('[clearWebViewCache] 当前 WebView 缓存已清除')
- logMessages.push('当前 WebView 缓存已清除')
- }
-
- // 清除所有 WebView 的缓存
- const allWebviews = plus.webview.all()
- if (allWebviews && allWebviews.length > 0) {
- allWebviews.forEach((webview) => {
- try {
- // 清除缓存
- if (webview && typeof webview.clearCache === 'function') {
- webview.clearCache()
- }
-
- // 清除 Cookie 和存储
- if (webview && typeof webview.evalJS === 'function') {
- webview.evalJS(`
- try {
- // 清除所有 Cookie
- document.cookie.split(";").forEach(function(c) {
- document.cookie = c.replace(/^ +/, "").replace(/=.*/, "=;expires=" + new Date().toUTCString() + ";path=/");
- });
- // 清除存储
- if (window.localStorage) localStorage.clear();
- if (window.sessionStorage) sessionStorage.clear();
- console.log('[WebView.evalJS] Cookie 和存储已清除');
- } catch (e) {
- console.error('[WebView.evalJS] 清除失败:', e);
- }
- `)
- }
- } catch (e) {
- console.error('[clearWebViewCache] 处理 WebView 失败:', e)
- }
- })
- console.log('[clearWebViewCache] 所有 WebView 缓存和 Cookie 已清除,共 ' + allWebviews.length + ' 个')
- logMessages.push(`所有 WebView 已清除 (${allWebviews.length}个)`)
+ try {
+ if (plus.storage) {
+ plus.storage.clear()
+ }
+ } catch (e) {
+ console.error('[clearWebViewCache] 清除 plus.storage 失败:', e)
}
// #endif
- // #ifndef APP-PLUS
- console.log('[clearWebViewCache] 非 APP-PLUS 环境,已清除 uni.storage')
- logMessages.push('非 APP-PLUS 环境')
- // #endif
-
- // 显示清除结果
- uni.showToast({
- title: '缓存已清除',
- icon: 'success',
- duration: 2000
- })
-
+ // 复用进入直播间前的彻底清理逻辑(Android CookieManager/WebStorage、iOS NSHTTPCookieStorage/WKWebsiteDataStore)
+ clearWebViewData()
} catch (error) {
console.error('[clearWebViewCache] 清除缓存失败:', error)
- logMessages.push('异常: ' + error.message)
-
- uni.showToast({
- title: '缓存清除失败',
- icon: 'none',
- duration: 2000
- })
}
-
- // 开发调试:显示详细日志
- console.log('[clearWebViewCache] 执行完成,日志:', logMessages.join(' | '))
}
/**
diff --git a/traditionalApp/pages/webview/webview.vue b/traditionalApp/pages/webview/webview.vue
index b8fe59d..951bbb6 100644
--- a/traditionalApp/pages/webview/webview.vue
+++ b/traditionalApp/pages/webview/webview.vue
@@ -10,6 +10,7 @@
<script setup lang="ts">
import { ref } from 'vue'
import { onLoad, onUnload } from '@dcloudio/uni-app'
+import { clearWebViewData } from '@/utils/webview-cache.js'
const webViewUrl = ref('')
let currentWebviewInstance: any = null
@@ -44,139 +45,11 @@
})
/**
- * 页面卸载时清除 WebView 缓存和 Cookie
+ * 页面卸载时不再清理缓存:清理集中在进入直播间前与退出登录时执行。
*/
onUnload(() => {
- console.log('[WebView] 页面卸载,开始清除缓存')
- clearWebViewData()
+ console.log('[WebView] 页面卸载')
})
-
-/**
- * 清除所有 WebView 的缓存、Cookie 和存储数据。
- * 原生 API 可清掉 HttpOnly cookie 和按域名隔离的 localStorage;
- * evalJS 仅作为兜底,清掉非 HttpOnly cookie 和当前页 storage。
- */
-function clearWebViewData() {
- try {
- // #ifdef APP-PLUS
- // 1. 原生 API 清理(核心:能清掉 HttpOnly cookie 和所有域名的 localStorage)
- const platform = String(uni.getSystemInfoSync().platform || '').toLowerCase()
- if (platform === 'android') {
- clearAndroidWebViewData()
- } else if (platform === 'ios') {
- clearIOSWebViewData()
- }
-
- // 2. plus.webview API 兜底:清 HTTP 资源缓存,并注入 JS 清当前页 cookie/storage
- try {
- const allWebviews = plus.webview.all()
- if (allWebviews && allWebviews.length > 0) {
- allWebviews.forEach((webview) => {
- try {
- if (webview && typeof webview.clearCache === 'function') {
- webview.clearCache()
- }
- if (webview && typeof webview.evalJS === 'function') {
- webview.evalJS(`
- try {
- document.cookie.split(";").forEach(function(c) {
- document.cookie = c.replace(/^ +/, "").replace(/=.*/, "=;expires=" + new Date().toUTCString() + ";path=/");
- });
- if (window.localStorage) localStorage.clear();
- if (window.sessionStorage) sessionStorage.clear();
- } catch (e) {}
- `)
- }
- } catch (e) {}
- })
- console.log('[WebView] 所有 WebView HTTP 缓存已清除,共 ' + allWebviews.length + ' 个')
- }
- } catch (e) {}
- // #endif
- } catch (error) {
- console.error('[WebView] 清除数据失败:', error)
- }
-}
-
-/**
- * Android 原生清理:清所有域名 Cookie(含 HttpOnly)+ WebStorage + 表单数据。
- */
-function clearAndroidWebViewData() {
- try {
- // 清所有域名 Cookie(包括 HttpOnly),CookieManager 是全局按域名共享的
- const CookieManager = plus.android.importClass('android.webkit.CookieManager')
- if (CookieManager) {
- const cm = CookieManager.getInstance()
- try { cm.removeAllCookie() } catch (e) {} // 老版本 API(API 21 以下)
- try { cm.flush() } catch (e) {} // 立即写入磁盘
- console.log('[WebView][Android] CookieManager 已清所有 Cookie')
- }
-
- // 清所有域名的 localStorage / sessionStorage(WebStorage 是全局按域名共享的)
- const WebStorage = plus.android.importClass('android.webkit.WebStorage')
- if (WebStorage) {
- const ws = WebStorage.getInstance()
- try { ws.deleteAllData() } catch (e) {}
- console.log('[WebView][Android] WebStorage 已清所有 localStorage')
- }
-
- // 清表单数据和密码(可选)
- try {
- const WebViewDatabase = plus.android.importClass('android.webkit.WebViewDatabase')
- const context = plus.android.runtime.appContext
- if (WebViewDatabase && context) {
- const db = WebViewDatabase.getInstance(context)
- if (db && typeof db.clearFormData === 'function') {
- db.clearFormData()
- }
- }
- } catch (e) {}
- } catch (e) {
- console.error('[WebView][Android] 原生清理失败:', e)
- }
-}
-
-/**
- * iOS 原生清理:清 NSHTTPCookieStorage 所有 Cookie;并用 WKWebsiteDataStore 清 WKWebView 数据。
- */
-function clearIOSWebViewData() {
- // 1. NSHTTPCookieStorage.deleteAllCookies(UIWebView 与部分 WKWebView 共享)
- try {
- const NSHTTPCookieStorage = plus.ios.importClass('NSHTTPCookieStorage')
- if (NSHTTPCookieStorage) {
- const storage = NSHTTPCookieStorage.sharedHTTPCookieStorage()
- if (storage) {
- try { plus.ios.invoke(storage, 'deleteAllCookies') } catch (e) {}
- console.log('[WebView][iOS] NSHTTPCookieStorage 已清所有 Cookie')
- }
- }
- } catch (e) {
- console.error('[WebView][iOS] NSHTTPCookieStorage 清理失败:', e)
- }
-
- // 2. WKWebsiteDataStore.removeDataOfTypes(iOS 9+,清 WKWebView 的 cookie/localStorage/cache)
- // block 部分用空 block 代替,调用 plus.ios.invoke
- try {
- const WKWebsiteDataStore = plus.ios.importClass('WKWebsiteDataStore')
- if (!WKWebsiteDataStore) {
- return
- }
- const allTypes = WKWebsiteDataStore.allWebsiteDataTypes()
- const defaultStore = WKWebsiteDataStore.defaultDataStore()
- const NSDate = plus.ios.importClass('NSDate')
- const distantPast = NSDate ? NSDate.distantPast() : null
- // completionHandler 传一个空 block,避免 native 崩溃
- const noopHandler = function () {}
- try {
- plus.ios.invoke(defaultStore, 'removeDataOfTypes:modifiedAt:completionHandler:', allTypes, distantPast, noopHandler)
- console.log('[WebView][iOS] WKWebsiteDataStore 已清所有数据')
- } catch (e) {
- console.error('[WebView][iOS] WKWebsiteDataStore 调用失败:', e)
- }
- } catch (e) {
- console.error('[WebView][iOS] WKWebsiteDataStore 初始化失败:', e)
- }
-}
/**
* 解码路由参数,异常时回退为空字符串。
diff --git a/traditionalApp/utils/webview-cache.js b/traditionalApp/utils/webview-cache.js
new file mode 100644
index 0000000..294480e
--- /dev/null
+++ b/traditionalApp/utils/webview-cache.js
@@ -0,0 +1,128 @@
+/**
+ * 清除所有 WebView 的缓存、Cookie 和存储数据。
+ * 原生 API 可清掉 HttpOnly cookie 和按域名隔离的 localStorage;
+ * evalJS 仅作为兜底,清掉非 HttpOnly cookie 和当前页 storage。
+ *
+ * 进入微赞直播间前、退出登录时统一调用此函数,保证清理逻辑一致。
+ */
+export function clearWebViewData() {
+ try {
+ // #ifdef APP-PLUS
+ // 1. 原生 API 清理(核心:能清掉 HttpOnly cookie 和所有域名的 localStorage)
+ const platform = String(uni.getSystemInfoSync().platform || '').toLowerCase()
+ if (platform === 'android') {
+ clearAndroidWebViewData()
+ } else if (platform === 'ios') {
+ clearIOSWebViewData()
+ }
+
+ // 2. plus.webview API 兜底:清 HTTP 资源缓存,并注入 JS 清当前页 cookie/storage
+ try {
+ const allWebviews = plus.webview.all()
+ if (allWebviews && allWebviews.length > 0) {
+ allWebviews.forEach((webview) => {
+ try {
+ if (webview && typeof webview.clearCache === 'function') {
+ webview.clearCache()
+ }
+ if (webview && typeof webview.evalJS === 'function') {
+ webview.evalJS(`
+ try {
+ document.cookie.split(";").forEach(function(c) {
+ document.cookie = c.replace(/^ +/, "").replace(/=.*/, "=;expires=" + new Date().toUTCString() + ";path=/");
+ });
+ if (window.localStorage) localStorage.clear();
+ if (window.sessionStorage) sessionStorage.clear();
+ } catch (e) {}
+ `)
+ }
+ } catch (e) {}
+ })
+ console.log('[WebView] 所有 WebView HTTP 缓存已清除,共 ' + allWebviews.length + ' 个')
+ }
+ } catch (e) {}
+ // #endif
+ } catch (error) {
+ console.error('[WebView] 清除数据失败:', error)
+ }
+}
+
+/**
+ * Android 原生清理:清所有域名 Cookie(含 HttpOnly)+ WebStorage + 表单数据。
+ */
+function clearAndroidWebViewData() {
+ try {
+ // 清所有域名 Cookie(包括 HttpOnly),CookieManager 是全局按域名共享的
+ const CookieManager = plus.android.importClass('android.webkit.CookieManager')
+ if (CookieManager) {
+ const cm = CookieManager.getInstance()
+ try { cm.removeAllCookie() } catch (e) {} // 老版本 API(API 21 以下)
+ try { cm.flush() } catch (e) {} // 立即写入磁盘
+ console.log('[WebView][Android] CookieManager 已清所有 Cookie')
+ }
+
+ // 清所有域名的 localStorage / sessionStorage(WebStorage 是全局按域名共享的)
+ const WebStorage = plus.android.importClass('android.webkit.WebStorage')
+ if (WebStorage) {
+ const ws = WebStorage.getInstance()
+ try { ws.deleteAllData() } catch (e) {}
+ console.log('[WebView][Android] WebStorage 已清所有 localStorage')
+ }
+
+ // 清表单数据和密码(可选)
+ try {
+ const WebViewDatabase = plus.android.importClass('android.webkit.WebViewDatabase')
+ const context = plus.android.runtime.appContext
+ if (WebViewDatabase && context) {
+ const db = WebViewDatabase.getInstance(context)
+ if (db && typeof db.clearFormData === 'function') {
+ db.clearFormData()
+ }
+ }
+ } catch (e) {}
+ } catch (e) {
+ console.error('[WebView][Android] 原生清理失败:', e)
+ }
+}
+
+/**
+ * iOS 原生清理:清 NSHTTPCookieStorage 所有 Cookie;并用 WKWebsiteDataStore 清 WKWebView 数据。
+ */
+function clearIOSWebViewData() {
+ // 1. NSHTTPCookieStorage.deleteAllCookies(UIWebView 与部分 WKWebView 共享)
+ try {
+ const NSHTTPCookieStorage = plus.ios.importClass('NSHTTPCookieStorage')
+ if (NSHTTPCookieStorage) {
+ const storage = NSHTTPCookieStorage.sharedHTTPCookieStorage()
+ if (storage) {
+ try { plus.ios.invoke(storage, 'deleteAllCookies') } catch (e) {}
+ console.log('[WebView][iOS] NSHTTPCookieStorage 已清所有 Cookie')
+ }
+ }
+ } catch (e) {
+ console.error('[WebView][iOS] NSHTTPCookieStorage 清理失败:', e)
+ }
+
+ // 2. WKWebsiteDataStore.removeDataOfTypes(iOS 9+,清 WKWebView 的 cookie/localStorage/cache)
+ // block 部分用空 block 代替,调用 plus.ios.invoke
+ try {
+ const WKWebsiteDataStore = plus.ios.importClass('WKWebsiteDataStore')
+ if (!WKWebsiteDataStore) {
+ return
+ }
+ const allTypes = WKWebsiteDataStore.allWebsiteDataTypes()
+ const defaultStore = WKWebsiteDataStore.defaultDataStore()
+ const NSDate = plus.ios.importClass('NSDate')
+ const distantPast = NSDate ? NSDate.distantPast() : null
+ // completionHandler 传一个空 block,避免 native 崩溃
+ const noopHandler = function () {}
+ try {
+ plus.ios.invoke(defaultStore, 'removeDataOfTypes:modifiedAt:completionHandler:', allTypes, distantPast, noopHandler)
+ console.log('[WebView][iOS] WKWebsiteDataStore 已清所有数据')
+ } catch (e) {
+ console.error('[WebView][iOS] WKWebsiteDataStore 调用失败:', e)
+ }
+ } catch (e) {
+ console.error('[WebView][iOS] WKWebsiteDataStore 初始化失败:', e)
+ }
+}
--
Gitblit v1.7.1