Android WebView 加载 file:// 离线页面调试教程

本文记录一种调试场景:当前已经通过 Chrome DevTools 连接到 Android App 内的 WebView,希望让这个 WebView 直接加载手机本地的 file:// 离线页面。

示例目标地址:

text 复制代码
file:///storage/emulated/0/Android/data/com.example.app/index.html?file=<path_id>/<resource_id>

1. 为什么 Console 里直接跳转会失败

在 Chrome DevTools Console 里执行:

js 复制代码
window.location.href = 'file:///storage/emulated/0/Android/data/com.example.app/index.html?file=<path_id>/<resource_id>'

或:

js 复制代码
location.replace('file:///storage/emulated/0/Android/data/com.example.app/index.html?file=<path_id>/<resource_id>')

可能会报:

text 复制代码
Not allowed to load local resource: file://...

原因是:当前页面脚本从 http://https:// 页面主动跳转到 file:// 本地资源时,会被 Chromium/WebView 的安全策略拦截。

这不是 URL 拼写问题,而是页面上下文发起 file:// 导航被禁止。

2. 不要把 file:// 粘到地址栏

如果把下面这种地址直接粘到 Chrome 或 DevTools 的地址栏:

text 复制代码
file:///storage/emulated/0/Android/data/...

Chrome 有时会把它当成普通搜索或网页地址处理,出现自动拼接 http:// 的情况。

调试 WebView 时,不建议通过地址栏输入这种手机端本地路径。

3. 用 Protocol Monitor 发送 Page.navigate

更合适的方式是通过 Chrome DevTools Protocol 让调试器发起导航,而不是让页面 JS 发起导航。

打开 Protocol Monitor

  1. 打开连接 WebView 的 DevTools 页面。
  2. Cmd + Shift + P,Windows/Linux 使用 Ctrl + Shift + P
  3. 搜索:
text 复制代码
Protocol Monitor
  1. 选择:
text 复制代码
Show Protocol Monitor

如果搜不到:

  1. 打开 DevTools 右上角齿轮 Settings
  2. 进入 Experiments
  3. 勾选 Protocol Monitor
  4. 关闭并重新打开 DevTools。
  5. 再通过命令面板打开 Show Protocol Monitor

正确发送方式

在 Protocol Monitor 里,方法名填:

text 复制代码
Page.navigate

参数填:

json 复制代码
{
  "url": "file:///storage/emulated/0/Android/data/com.example.app/index.html?file=<path_id>/<resource_id>"
}

注意:不要把下面这种函数调用整体填进去:

js 复制代码
Page.navigate({"url":"file:///..."})

否则会报:

json 复制代码
{
  "code": -32601,
  "message": "'Page.navigate({...})' wasn't found"
}

这个报错表示 DevTools 把整段 Page.navigate({...}) 当成了 method 名,而不是调用了 Page.navigate 方法。

如果 Protocol Monitor 只有单行 JSON-RPC 输入,可以尝试:

json 复制代码
{"id":1,"method":"Page.navigate","params":{"url":"file:///storage/emulated/0/Android/data/com.example.app/index.html?file=<path_id>/<resource_id>"}}

4. URL 参数里的 https 要编码

如果原始参数里有:

text 复制代码
cdn=https://cdn.example.com

建议编码成:

text 复制代码
cdn=https%3A%2F%2Fcdn.example.com

否则嵌套 URL 容易在解析 query 参数时出问题。

5. 如果 Page.navigate 也失败

如果通过 Protocol Monitor 发送 Page.navigate 后仍然失败,例如出现:

text 复制代码
Not allowed to load local resource

或:

text 复制代码
net::ERR_ACCESS_DENIED

或页面空白,那通常说明 WebView 本身没有允许访问本地文件。

这时需要从 App 代码侧加载,而不是从 DevTools 侧强行跳转。

Kotlin 示例:

kotlin 复制代码
webView.settings.allowFileAccess = true
webView.settings.allowFileAccessFromFileURLs = true
webView.settings.allowUniversalAccessFromFileURLs = true

webView.loadUrl(
    "file:///storage/emulated/0/Android/data/com.example.app/index.html?file=<path_id>/<resource_id>"
)

Java 示例:

java 复制代码
webView.getSettings().setAllowFileAccess(true);
webView.getSettings().setAllowFileAccessFromFileURLs(true);
webView.getSettings().setAllowUniversalAccessFromFileURLs(true);

webView.loadUrl(
    "file:///storage/emulated/0/Android/data/com.example.app/index.html?file=<path_id>/<resource_id>"
);

6. 判断问题属于哪一类

现象 可能原因 处理方式
地址栏自动拼 http:// 地址栏把输入当普通网页地址处理 不用地址栏,改用 DevTools Protocol
Console 报 Not allowed to load local resource 页面 JS 不能从 http/https 跳到 file 不用 window.location.href,改用 Page.navigate 或 App 侧 loadUrl
Protocol Monitor 报 -32601 method 填错,把函数调用当方法名 method 填 Page.navigate,params 单独填 JSON
Page.navigate 后仍报 ERR_ACCESS_DENIED WebView 文件访问权限不允许 App 侧开启 file access 并调用 webView.loadUrl
页面打开但资源加载失败 file 页面内跨域访问 http/https 或其他 file 资源受限 检查 allowFileAccessFromFileURLsallowUniversalAccessFromFileURLs

7. 推荐调试顺序

  1. 先确认文件真实存在于手机路径:
bash 复制代码
adb shell ls -l /storage/emulated/0/Android/data/com.example.app/index.html
  1. 用 Chrome DevTools 连接目标 WebView。

  2. 打开 Protocol Monitor

  3. 发送 Page.navigate,不要在 Console 里执行 window.location.href

  4. 如果仍然被拦截,改为 App 代码侧 webView.loadUrl(fileUrl)

  5. 如果页面能打开但内容异常,再检查 WebView 的 file access 相关设置和页面内资源路径。

相关推荐
齊家治國平天下2 小时前
Android 14 Vehicle HAL (VHAL) 设计与实现深度解析
android·aaos·carservice·车载开发·android 14·vhal·vehicle hal
钛态3 小时前
前端安全防线:CSRF 攻击链路与双重 Token 校验的工程实现
前端·vue·react·web
张拭心4 小时前
技术管理笔记:让我“燃尽”的一天
前端
不好听6135 小时前
BFF 架构实战:从前端直调 API 到加入中间层
前端·架构
不好听6135 小时前
前端跨域完全指南:从为什么报错到三种解决方案
前端
三8445 小时前
路由策略/控制 配置双点双向路由重发布
服务器·前端·javascript
Qimooidea5 小时前
祁木 CAD Translator 工程图纸出海实战指南
服务器·前端·安全
小林ixn5 小时前
从BFF到SSE:我在Vue项目里藏了个“AI翻译官”
前端·vue.js·vite
元气少女小圆丶7 小时前
unity发布web嵌入到前端页面的接受参数
前端·unity·webgl
工业HMI实战笔记7 小时前
【拯救HMI】:低碳制造:自动化技术如何助力企业节能降耗
运维·前端·自动化·交互·制造