开发Hybrid App时,file:///加载本地html,无
新上手一个混合开发APP的项目,需要IOS和android通过webview调用本地html文件,要求能显示H5页面并产生交互。
因为之前没接触过混合开发,项目在一开始就遇到了问题,ios和android在调用本地html文件时,可以引入资源,但js不能读写加载的内容。如路由导航功能渲染的页面无法显示,以及数据无法加载。
后面尝试把html文件放到服务器上,webview通过请求远程地址加载html文件,发现显示正常,内容和数据都能正常渲染。于是猜测是域名URL的问题,在百度上搜索“file:///加载html文件”时,发现一个关键词——“同源策略”。
1.1、先来说说什么是源
源(origin)就是协议、域名和端口号,若地址里面的协议、域名和端口号均相同则属于同源。
以下是相对于http://www.a.com/test/index.html 的同源检测
• http://www.a.com/dir/page.html ----成功
• http://www.child.a.com/test/index.html ----失败,域名不同
• https://www.a.com/test/index.html ----失败,协议不同
• http://www.a.com:8080/test/index.html ----失败,端口号不同
1.2.什么是同源策略?同源策略是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源。所以http://a.com下的js脚本采用ajax读取http://b.com里面的文件数据是会报错的。
• 不受同源策略限制的:1、页面中的链接,重定向以及表单提交是不会受到同源策略限制的。2、跨域资源的引入是可以的。但是js不能读写加载的内容。如嵌入到页面中的<script src="..."></script>,<img>,<link>,<iframe>等。
在明白什么是同源策略后,问题差不多已经找到原因了,继续在网上查找了一番,看到一篇文章——WebView的优化--处理WebView的容易忽略的漏洞,在这篇文章里面找到了安卓端的解决方法:
setAllowFileAccess()
// 设置是否允许 WebView 使用 File 协议
webView.getSettings().setAllowFileAccess(true);
// 默认设置为true,即允许在 File 域下执行任意 JavaScript 代码
1:禁用 file 协议;
webView.getSettings().setAllowFileAccess(false);
这样虽然最方便,但同时也限制了WebView 的功能,使其不能加载本地的 html 文件。
2:对于需要使用 file 协议的应用,禁止 file 协议加载 JavaScript。;
setAllowFileAccess(true);
// 禁止 file 协议加载 JavaScript
if (url.startsWith("file://") {
setJavaScriptEnabled(false);
} else {
setJavaScriptEnabled(true);
}
setAllowFileAccessFromFileURLs()
// 设置是否允许通过 file url 加载的 Js代码读取其他的本地文件
webView.getSettings().setAllowFileAccessFromFileURLs(true);
// 在Android 4.1前默认允许
// 在Android 4.1后默认禁止
这样不安全,解决办法直接关掉setAllowFileAccessFromFileURLs(false);
setAllowUniversalAccessFromFileURLs()
// 设置是否允许通过 file url 加载的 Javascript 可以访问其他的源(包括http、https等源)
webView.getSettings().setAllowUniversalAccessFromFileURLs(true);
// 在Android 4.1前默认允许(setAllowFileAccessFromFileURLs()不起作用)
// 在Android 4.1后默认禁止
这个一般还好,如果想保证资源的安全的话,建议关掉
setAllowUniversalAccessFromFileURLs(false);
setJavaScriptEnabled()
// 设置是否允许 WebView 使用 JavaScript(默认是不允许)
webView.getSettings().setJavaScriptEnabled(true);
// 但很多应用(包括移动浏览器)为了让 WebView 执行 http 协议中的 JavaScript,都会主动设置为true,不区别对待是非常危险的。
android应用重新设置后,页面正常显示,内容和数据都可以渲染,问题解决一半,剩下的就是找到ios类似的方法。感谢博主Vincent__Lee,附上文章链接:WebView的优化--处理WebView的容易忽略的漏洞 - li15225271052的博客 - CSDN博客