背景
设备测试流程系统,页面由h5(react)编写,外面套个安卓的壳。h5代码存储在安卓项目的assets静态资源目录下,安卓端Java代码中通过loadUrl方式加载index.html静态页面,如下:
private var url: String = "file:////android_asset/dist/index.html"
...
webView.loadUrl(url)
当h5页面中有http请求时,会报跨域问题,提示错误: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. 原因是file和http是两种协议,属于跨协议的跨域问题。
安卓端解决办法
参考1:android——webview开发:跨域请求问题的解决方式之一
参考2:大体意思是允许file文件进行跨域请求任意源的数据 WebSettings.AllowUniversalAccessFromFileURLs Property
下面是kt代码,对安卓不是很了解,懂的可以看下
val webSettings: WebSettings = webView.settings
webSettings.allowUniversalAccessFromFileURLs = true
webSettings.allowFileAccess = false
webSettings.setSupportZoom(false)
webSettings.useWideViewPort = true
webSettings.javaScriptEnabled = true
webSettings.databaseEnabled = true
webSettings.domStorageEnabled = true
webSettings.loadWithOverviewMode = true
webSettings.loadsImagesAutomatically = true
webSettings.defaultTextEncodingName = "UTF-8"
webView.loadUrl(url)
webView.webChromeClient = WebChromeClient()
Log.i("webView", "before:${LazyUtil.toJson(deviceInfoDTO)}")
webView.addJavascriptInterface(JSInterface(LazyUtil.toJson(deviceInfoDTO)), "launcher")//定义laucher名称
前端如何通过jsInterface方式与安卓交互
本人比较懒,直接附上代码,(#^.^#)
if (window.launcher) { // 判断 launcher 对象是否存在
// 此处的 launcher 要和 安卓端定义的 launcher名称保持一致
// JS 调用 Android 的方法
// launcher.callAndroid(params);
let info = window.launcher.getDeviceInfo() //调用安卓的getDeviceInfo方法
callBack(info)
} else {
alert("launcher not found!");
}
构建项目时需要调整的地方
(1)修改publicPath
因为这里的前端项目是放在本地的,所以前端用webpack在生产(production)环境打包时,output的publicPath不能是相对路径(直接打开index.html会报错),解决办法改成绝对路径,如下。
(2)修改输出路径
目的是直接将dist包放到安卓项目预期目录下,如下:
output: {
path: getDir(['../app/src/main/assets/dist']),
publicPath: process.env.NODE_ENV === 'development' ? '/' : './',
filename: ...,
chunkFilename: ...,
...
}