Skip to content

Commit 613c0e7

Browse files
committed
fix(android): improve file request handling to support fallback to network resources (#129)
1 parent 86e84ae commit 613c0e7

1 file changed

Lines changed: 40 additions & 5 deletions

File tree

android/dimina/src/main/kotlin/com/didi/dimina/ui/view/WebViewCacheManager.kt

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -527,11 +527,19 @@ internal fun createWebViewClientWithInterceptor(
527527

528528
/**
529529
* 统一处理文件拦截请求的逻辑
530-
* 拦截file://协议的请求,从本地文件系统加载资源
530+
* 拦截file://协议的请求,优先从本地文件系统加载资源
531+
*
532+
* 处理策略:
533+
* 1. 优先尝试作为本地文件加载
534+
* 2. 如果文件不存在,则判断可能是被错误解析的协议相对URL,转换为https://协议加载
535+
*
536+
* 这样可以兼容两种情况:
537+
* - 真正的本地文件:直接加载
538+
* - 被错误解析的网络资源:自动转换为https加载
531539
*
532540
* @param context 上下文对象
533541
* @param request WebView资源请求
534-
* @return 如果是文件协议请求且文件存在,返回WebResourceResponse;否则返回null
542+
* @return 如果是文件协议请求且文件存在,返回WebResourceResponse;如果文件不存在则尝试网络加载;否则返回null
535543
*/
536544
internal fun handleFileInterceptRequest(
537545
context: Context,
@@ -541,15 +549,42 @@ internal fun handleFileInterceptRequest(
541549

542550
if (url.startsWith(FILE_PROTOCOL)) {
543551
try {
544-
val localFile = getFilesFile(context, url.substring(FILE_PROTOCOL.length))
552+
// 提取file://协议后的路径部分
553+
val pathAfterProtocol = url.substring(FILE_PROTOCOL.length)
554+
555+
// 优先尝试作为本地文件加载
556+
val localFile = getFilesFile(context, pathAfterProtocol)
545557
if (localFile.exists()) {
546558
LogUtils.d(WEBVIEW_TAG, "Loading file from local: $url")
547559
val mimeType = MimeTypeMap.getSingleton()
548560
.getMimeTypeFromExtension(MimeTypeMap.getFileExtensionFromUrl(url))
549561
?: "text/html" // Fallback MIME type
550562
return WebResourceResponse(mimeType, "UTF-8", FileInputStream(localFile))
551-
} else {
552-
LogUtils.e(WEBVIEW_TAG, "intercepting file: $url is not existed")
563+
}
564+
565+
// 文件不存在,可能是被错误解析的协议相对URL,尝试转换为https://协议加载网络资源
566+
LogUtils.d(WEBVIEW_TAG, "Local file not found: $url")
567+
LogUtils.d(WEBVIEW_TAG, "Attempting to load as network resource via https")
568+
569+
val correctedUrl = "https:/${pathAfterProtocol}" // 转换为 https://domain/path
570+
LogUtils.d(WEBVIEW_TAG, "Corrected URL: $correctedUrl")
571+
572+
try {
573+
val connection = java.net.URL(correctedUrl).openConnection()
574+
connection.connectTimeout = 5000
575+
connection.readTimeout = 10000
576+
val inputStream = connection.getInputStream()
577+
val mimeType = connection.contentType?.split(";")?.firstOrNull()?.trim()
578+
?: MimeTypeMap.getSingleton()
579+
.getMimeTypeFromExtension(MimeTypeMap.getFileExtensionFromUrl(correctedUrl))
580+
?: "application/octet-stream"
581+
582+
LogUtils.d(WEBVIEW_TAG, "Successfully loaded network resource: $correctedUrl")
583+
return WebResourceResponse(mimeType, "UTF-8", inputStream)
584+
} catch (e: Exception) {
585+
LogUtils.e(WEBVIEW_TAG, "Failed to load network resource: $correctedUrl", e)
586+
// 返回null,让WebView按默认方式处理
587+
return null
553588
}
554589
} catch (e: Exception) {
555590
LogUtils.e(WEBVIEW_TAG, "Error intercepting file: $url", e)

0 commit comments

Comments
 (0)