Android本地WebView下file协议HTML动态加载JS遇CORS问题求解决方案
可行解决方案
方案1:Android端主动注入对应JS数据
该方案无需修改前端代码,仅在Android原生层处理即可完全避开file协议的CORS限制:
- 拦截WebView加载请求,从加载URL中提取
no参数值 - 读取
assets目录下对应data_{no}.js的文本内容 - 待HTML页面加载完成后,将读取到的JS内容通过WebView API注入页面执行
Android端代码示例(Kotlin):
webView.webViewClient = object : WebViewClient() { override fun onPageFinished(view: WebView?, url: String?) { super.onPageFinished(view, url) // 提取url中的no参数 val no = Uri.parse(url).getQueryParameter("no") ?: "1" // 读取对应JS文件内容 val jsContent = assets.open("data/data_$no.js").bufferedReader().use { it.readText() } // 注入JS执行 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { webView.evaluateJavascript(jsContent, null) } else { webView.loadUrl("javascript:$jsContent") } } } // 加载目标页面 webView.loadUrl("file:///android_asset/folder/file.html?no=1")
方案2:前端动态创建script标签加载
该方案无需修改Android原生代码,仅前端实现即可。注意不要使用基于XMLHttpRequest实现的getScript/AJAX(会触发CORS拦截),script标签的资源加载天生不受同源策略限制,file协议下可正常使用:
前端代码示例:
// 提取url参数 function getQueryParam(name) { const reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); const r = window.location.search.substr(1).match(reg); return r ? decodeURIComponent(r[2]) : "1"; } const no = getQueryParam('no'); // 动态创建script标签加载对应数据文件 const script = document.createElement('script'); // 路径填写相对于当前HTML文件的相对路径即可 script.src = `./data/data_${no}.js`; // 加载完成后执行渲染逻辑 script.onload = function() { // 可直接使用data变量做页面渲染 renderPage(data); } document.head.appendChild(script);
方案3:合并所有数据为单个JS文件
如果100多个JS文件的总数据量不大(文本类数据通常压缩后体积很小),可以将所有数据合并为单个JS文件,按no作为索引key,仅需一次文件IO,加载速度远快于加载100个分散的JS文件:
合并后的all_data.js示例:
const allData = { 1: [{no1:"xxx", no2:"xxx", no3:"xxx"}], 2: [{no1:"xxx", no2:"xxx", no3:"xxx"}], // 剩余所有数据依次录入 }
HTML中仅需引入一次该文件:
<script src="./data/all_data.js"></script>
使用时直接读取对应索引的数据即可:
const no = getQueryParam('no'); const data = allData[no]; renderPage(data);
内容的提问来源于stack exchange,提问作者Reza Febrian
相关产品推荐
相关产品推荐

