父页面列表通过window.open打开的子页面,子页面处理完毕刷新父页面(跨域情况下)

本文介绍了在不同版本的Internet Explorer中实现子页面与父页面通信的方法。对于IE8及以上版本,利用`postMessage` API可以在处理完子页面内容后向父页面发送'freshen'消息,触发父页面的`message`事件来刷新列表。而对于IE8及以下版本,父页面将刷新方法绑定到`window`对象上,并创建一个外部HTML,子页面通过`iframe`加载这个HTML来调用父页面的刷新方法,达到同样的效果。

1. ie8以上
子页面在处理完毕后通过 postMessage 发送消息

window.opener.postMessage('freshen', '*');

父页面监听

window.addEventListener('message', e => {
	if(e.data === 'freshen') {
		//刷新列表的方法
	}
})

2. ie8及以下
父页面把刷新方法绑定在window上

 window.freshen = () => {
    //刷新列表的方法
 }

同时在父页面项目的同一域名下,添加可供外部访问的html,里边js写上:

window.parent.opener.freshen();

子页面在处理完毕后,通过iframe访问这个html即可刷新父页面列表

package com.example.kanban import android.annotation.SuppressLint import android.os.Build import android.os.Bundle import android.os.Handler import android.os.Looper import android.util.Log import android.view.WindowManager import android.webkit.* import android.widget.Toast import androidx.appcompat.app.AppCompatActivity class MainActivity : AppCompatActivity() { private lateinit var webView: WebView private val handler = Handler(Looper.getMainLooper()) private var timeoutRunnable: Runnable? = null private var isMonitoringRequests = false private var pendingRequests = 0 private var lastRequestTime: Long = 0 @SuppressLint("SetJavaScriptEnabled") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // 启用硬件加速 window.setFlags( WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED ) webView = findViewById<WebView>(R.id.webView).apply { // 基础设置 settings.apply { javaScriptEnabled = true domStorageEnabled = true allowContentAccess = true allowFileAccess = true setSupportZoom(true) builtInZoomControls = true displayZoomControls = false cacheMode = WebSettings.LOAD_DEFAULT useWideViewPort = true loadWithOverviewMode = true // 解决ORB和安全问题 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { allowUniversalAccessFromFileURLs = true } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { safeBrowsingEnabled = false } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { mixedContentMode = WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE } } // 添加JavaScript接口 addJavascriptInterface(WebAppInterface(), "Android") webViewClient = object : WebViewClient() { override fun onPageStarted(view: WebView?, url: String?, favicon: android.graphics.Bitmap?) { super.onPageStarted(view, url, favicon) startRequestMonitoring() } override fun onPageFinished(view: WebView, url: String) { super.onPageFinished(view, url) injectRequestMonitoringScript() } override fun onReceivedError( view: WebView, request: WebResourceRequest, error: WebResourceError ) { super.onReceivedError(view, request, error) handleWebError("加载错误: ${error.description}") } override fun onReceivedHttpError( view: WebView, request: WebResourceRequest, errorResponse: WebResourceResponse ) { super.onReceivedHttpError(view, request, errorResponse) handleWebError("HTTP错误: ${errorResponse.statusCode}") } // 捕获URL变化 override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean { if (request != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { Log.d("WebView", "Loading URL: ${request.url}") // 这里可以添加处理URL变化的逻辑 } return super.shouldOverrideUrlLoading(view, request) } } } loadUrlWithRetry( "http://192.168.16.69:10011/#/show-draw?v=T1AnDCLWYo1fi0Ngzg5rW47U9W5joYwQ2F8aK1ENVaErtPWTiOlCN5y63ZsMTQObmlqGVKjmUceKYcvRfg%2BSXA%3D%3D&satoken=9a4d0de4-927d-41a0-b5c5-4440a0ddaae0", maxRetries = 2 ) } private fun startRequestMonitoring() { isMonitoringRequests = true pendingRequests = 0 timeoutRunnable?.let { handler.removeCallbacks(it) } timeoutRunnable = Runnable { if (isMonitoringRequests && pendingRequests > 0) { handleWebError("请求超时,仍有 $pendingRequests 个请求未完成") } }.also { handler.postDelayed(it, 30000) // 30秒超时 } } private fun injectRequestMonitoringScript() { webView.evaluateJavascript(""" (function() { if (!window.requestTracker) { window.requestTracker = { count: 0, completed: 0, activeRequests: new Set(), trackRequest: function(id) { this.count++; this.activeRequests.add(id); Android.requestStarted(id); return function(success, id) { this.completed++; this.activeRequests.delete(id); Android.requestCompleted(id, success); }.bind(this); }, // 获取当前所有活跃请求 getActiveRequests: function() { return Array.from(this.activeRequests); } }; // Hook XMLHttpRequest var originalOpen = XMLHttpRequest.prototype.open; XMLHttpRequest.prototype.open = function(method, url) { var requestId = 'xhr_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9); var tracker = window.requestTracker.trackRequest(requestId); this.addEventListener('loadend', function() { tracker(this.status >= 200 && this.status < 300, requestId); }.bind(this)); originalOpen.apply(this, arguments); }; // Hook fetch API var originalFetch = window.fetch; window.fetch = function(input, init) { var requestId = 'fetch_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9); window.requestTracker.trackRequest(requestId); return originalFetch.apply(this, arguments) .then(function(response) { window.requestTracker.activeRequests.delete(requestId); Android.requestCompleted(requestId, response.ok); return response; }) .catch(function(error) { window.requestTracker.activeRequests.delete(requestId); Android.requestCompleted(requestId, false); throw error; }); }; // 监控资源加载 function observeResourceLoading() { // 监听现有资源 document.querySelectorAll('img, script, link[rel="stylesheet"]').forEach(function(el) { if (!el.complete) { var requestId = el.tagName.toLowerCase() + '_' + Date.now() + '_' + el.src; var tracker = window.requestTracker.trackRequest(requestId); el.addEventListener('load', function() { tracker(true, requestId); }); el.addEventListener('error', function() { tracker(false, requestId); }); } }); // 监听新添加的资源 var observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { if (mutation.addedNodes) { mutation.addedNodes.forEach(function(node) { if (node.tagName && ['IMG', 'SCRIPT', 'LINK'].includes(node.tagName)) { if (node.tagName === 'LINK' && node.rel !== 'stylesheet') return; var requestId = node.tagName.toLowerCase() + '_' + Date.now() + '_' + (node.src || node.href); var tracker = window.requestTracker.trackRequest(requestId); node.addEventListener('load', function() { tracker(true, requestId); }); node.addEventListener('error', function() { tracker(false, requestId); }); } }); } }); }); observer.observe(document, { childList: true, subtree: true }); } // 页面加载完成后开始监控资源 if (document.readyState === 'complete') { observeResourceLoading(); } else { window.addEventListener('load', observeResourceLoading); } } })(); """.trimIndent(), null) } private fun loadUrlWithRetry(url: String, maxRetries: Int, currentRetry: Int = 0) { if (currentRetry > 0) { Toast.makeText(this, "正在重试 ($currentRetry/$maxRetries)...", Toast.LENGTH_SHORT).show() } webView.loadUrl(url) handler.postDelayed({ if (webView.progress < 90 && currentRetry < maxRetries) { loadUrlWithRetry(url, maxRetries, currentRetry + 1) } }, 10000) // 10秒后检查 } private fun handleWebError(message: String) { runOnUiThread { webView.loadData(""" <html> <body style='font-family:sans-serif;padding:20px;text-align:center;'> <h3 style='color:#d32f2f;'>加载遇到问题</h3> <p>$message</p> <button onclick="window.location.reload()" style='padding:10px 20px;background:#4285f4;color:white; border:none;border-radius:5px;margin-top:20px;'> 重新加载 </button> </body> </html> """, "text/html", "UTF-8") } } inner class WebAppInterface { @JavascriptInterface fun requestStarted() { pendingRequests++ lastRequestTime = System.currentTimeMillis() Log.d("WebView", "Request started. Pending: $pendingRequests") } @JavascriptInterface fun requestCompleted() { pendingRequests-- Log.d("WebView", "Request completed. Pending: $pendingRequests") if (pendingRequests <= 0) { handler.post { isMonitoringRequests = false timeoutRunnable?.let { handler.removeCallbacks(it) } Toast.makeText(this@MainActivity, "所有内容加载完成", Toast.LENGTH_SHORT).show() // 请求全部完成后,执行JavaScript刷新页面或通知页面更新 updatePageContent() } } } } private fun updatePageContent() { // 方法1: 执行JavaScript通知页面数据已更新 webView.evaluateJavascript(""" (function() { // 检查页面是否有更新数据的函数 if (window.onDataUpdated) { window.onDataUpdated(); } else { // 如果没有特定函数,尝试重新加载页面元素 document.dispatchEvent(new Event('dataUpdated')); } })(); """.trimIndent(), null) // 方法2: 可选的页面刷新(谨慎使用,可能导致无限循环) // webView.reload(); } override fun onDestroy() { handler.removeCallbacksAndMessages(null) webView.stopLoading() webView.destroy() super.onDestroy() } } 打开页面包含ajax请求,在电脑端浏览器都正常显示,但是在app上,部分接口没等返回数据,页面就加载完成了
最新发布
05-14
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值