Android API 30下Nativescript WebView出现ERR_ACCESS_DENIED错误如何解决?
问题原因
API 30 对WebView的本地资源访问权限默认收紧,默认禁止文件访问。你原来的配置是在WebView的加载事件(loadStarted/loadFinished)里修改设置,此时首次加载的请求已经发出,权限校验已经不通过,所以第一次报错。第二次进入页面时WebView实例复用了之前已经修改过的配置,所以加载正常。
解决方案
按以下步骤修改即可解决首次加载失败的问题:
- 提前配置WebView权限,不要在WebView自身的加载回调中修改。将配置逻辑移到页面初始化的
loaded事件中,此时WebView实例刚创建完成,还未开始加载内容。 - 补充开启本地文件跨源访问权限,这是API 30+加载本地HTML引用本地资源的必填配置。
- 配置完成后再给WebView赋值src,保证首次加载时配置已经生效。
代码修改示例
页面XML调整
移除WebView的src绑定,给页面添加loaded事件:
<Page loaded="onPageLoaded"> <GridLayout> <WebView id="annbyday" loadFinished="onLoadFinished" /> </GridLayout> </Page>
JS逻辑调整
const viewModel = require("tns-core-modules/data/observable").fromObject({ htmlsrcForDay: "你拼接好的HTML字符串" }); // 页面加载完成事件,早于WebView内容加载 exports.onPageLoaded = function(args) { const page = args.object; page.bindingContext = viewModel; const webView = page.getViewById("annbyday"); if (webView.android) { const webSettings = webView.android.getSettings(); // 基础资源访问权限 webSettings.setAllowFileAccess(true); webSettings.setAllowContentAccess(true); // 新增本地文件跨源访问权限,API30+必须开启 webSettings.setAllowFileAccessFromFileURLs(true); webSettings.setAllowUniversalAccessFromFileURLs(true); // 配置全部生效后再触发WebView加载 webView.src = viewModel.htmlsrcForDay; // 如果HTML引用的是assets下的资源,更推荐用原生方法加载,baseUrl指定资源根路径: // webView.android.loadDataWithBaseURL("file:///android_asset/", viewModel.htmlsrcForDay, "text/html", "UTF-8", null); } }; // 原有加载完成回调保留做错误处理即可 exports.onLoadFinished = function (args) { if (args.object.android) { args.error ? console.warn("加载失败:" + args.error) : console.log("加载成功"); } }
补充说明
你已配置的AndroidManifest.xml中的android:usesCleartextTraffic="true"不需要修改,如无其他明文请求需求也可以移除,不影响本地资源加载。
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

