webview打开本地Html文件
1.在路径前面加上file://
String filePath="file://"+path;
webView.loadUrl( filePath);
2.打开权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
3.启用JavaScript 设置本地访问权限
webView.getSettings().setJavaScriptEnabled(true);
webSettings.setAllowContentAccess(true);
4.如果js代码访问本地文件出现CORS跨源请求 可以通过重写WebViewClient的shouldInterceptRequest函数拦截请求并替换为本地资源
webView.setWebViewClient(new WebViewClient(){
@Nullable
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
// 获取请求的URL
String url = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
url = request.getUrl().toString();
}
// 检查URL是否符合你想要替换的file域规则
if (url.startsWith("file://")&&!url.contains(".html")) {
String path=url.replace("file://","");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
try {
InputStream inputStream = getAssets().open(path);
String mimeType = getMimeType(path);
return new WebResourceResponse(mimeType, "UTF-8", inputStream);
}catch (IOException e){
}
}
}
// 如果不是file域请求,则返回null继续加载
return super.shouldInterceptRequest(view, request);
}
});
private String getMimeType(String fileName) {
// 提取文件扩展名(统一转小写)
String extension = "";
int lastDotIndex = fileName.lastIndexOf('.');
if (lastDotIndex > 0) {
extension = fileName.substring(lastDotIndex + 1).toLowerCase();
}
// 常见 MIME 类型映射表
switch (extension) {
// 文本类
case "html":
case "htm":
return "text/html";
case "css":
return "text/css";
case "js":
return "application/javascript";
case "json":
return "application/json";
case "txt":
return "text/plain";
case "xml":
return "text/xml";
// 图片类
case "png":
return "image/png";
case "jpg":
case "jpeg":
return "image/jpeg";
case "gif":
return "image/gif";
case "webp":
return "image/webp";
case "svg":
return "image/svg+xml";
case "ico":
return "image/x-icon";
// 字体类
case "ttf":
return "font/ttf";
case "otf":
return "font/otf";
case "woff":
return "font/woff";
case "woff2":
return "font/woff2";
// 音视频
case "mp3":
return "audio/mpeg";
case "wav":
return "audio/wav";
case "mp4":
return "video/mp4";
case "webm":
return "video/webm";
// 其他
case "pdf":
return "application/pdf";
case "zip":
return "application/zip";
case "wasm":
return "application/wasm";
// 默认类型
default:
return "application/octet-stream";
}
}
5.如果H5项目中用到了Fetch 出现报错Fetch API cannot load 是因为Fetch不支持使用file://访问本地文件, 可以在html文件中处理下
如果是 arraybuffer 可以这样处理
<script>window.fetch=function fetchLocal(url, data) {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest
xhr.onload = function () {
resolve(new Response(xhr.response, { status: xhr.status }))
}
xhr.onerror = function () {
reject(new TypeError('Local request failed'))
}
xhr.open('GET', url)
xhr.responseType = "arraybuffer";
xhr.send(null)
})
}</script>
否则可以这样处理下
<script>window.fetch=function fetchLocal(url, data) {
return new Promise(function(resolve, reject) {
var xhr = new XMLHttpRequest
xhr.onload = function() {
resolve(new Response(xhr.responseText, {status: xhr.status}))
}
xhr.onerror = function() {
reject(new TypeError('Local request failed'))
}
xhr.open('GET', url)
xhr.send(data)
})
}</script>
至此,就可以离线访问本地的Unity,Cocos等H5游戏