> ## Content Index
> Fetch the complete content index at: https://iiong.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# Webview Vue 网页调试
- URL: https://iiong.com/webview-vue-debugger/
- Published: 2019-12-17T12:59:35.000Z
- Updated: 2026-06-22T15:32:17.000Z
- Description: 最近公司有个小项目类似这样，不过 App 这一块是利用 .Net 的 Xamarin 技术构建的 App，所以这就造成无法从浏览器调试数据。其次我利用 VueCli 生成静态页面，比编写原生的 HTML 页面高效多了，但同样无法抓取到页面动态数据的抓取。
- Author: 淮城一只猫
- Tags: 奇技淫巧, Vue.js, Web 前端

### Cap1 前言

转入前端的时候，就一直做 Hybrid App 开发，所以从 `React Native` 到 简单的 `Mui`、 `Api Cloud` 都尝试过，除了一些主流的开发方式，基本都有很好的调试工具，像 `RN` 都会有 `ReactNativeDebugger` 之类的工具。但由于公司需求，需要简单的 `webview` 网页开发的时候，`RN` 显然很笨重了，所以利用 `Mui.js` 真机框架去完成需求。最近公司有个小项目类似这样，不过 `App` 这一块是利用 `.Net` 的 `Xamarin` 技术构建的 `App`，然后里面一些方法需要端能力才能调用数据，所以这就造成无法从浏览器调试数据。其次我利用 `VueCli` 生成静态页面，比编写原生的 `HTML` 页面高效多了，但同样无法抓取到页面动态数据的抓取。

### Cap2 善用 window.alert 方法

这种方法算是调试中最傻最简单，不过在后面数据多的时候联调的时候就相对麻烦了，这里就不再描述。

### Cap3 使用 Webview Debug

`Webview Debug` 调试方法相对而言很好了，使用过程和网页调试的控制台一模一样，基本上没什么限制，对于硬件来讲只支持 `Android 4.4 (KitKat)以及以上版本` 环境下，并且使用 `Chrome` 浏览器来支持该功能。

只需要在 `Android` 环境下添加下面代码即可支持：

```java
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
    if (0 != (getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE))
    { WebView.setWebContentsDebuggingEnabled(true); }
}

```

如果你懒的话，也可以尝试使用 `Xposed` 框架支持 `Webview Debug`模式：[WebViewDebugHook](https://github.com/feix760/WebViewDebugHook?ref=iiong.com)，可以利用虚拟机尝试，毕竟虚拟机包含 `root` 权限。

然后打开 `chrome://inspect` 地址会看到调试的设备，调试方法和网页调试一样，这里就不再描述了。

参考：

- [远程调试 WebView](https://developers.google.com/web/tools/chrome-devtools/remote-debugging/webviews?hl=zh-cn&ref=iiong.com)
- [Android 设备的远程调试入门](https://developers.google.com/web/tools/chrome-devtools/remote-debugging?ref=iiong.com)

但对于 `Vue.js` 单应用页面来说，页面包含的数据是不好抓取的，变量名混淆，页面数据压缩等等，造就页面调试进一步困难，针对于这个现象也很简单，直接将生成文件编译成和 `npm run dev` 环境即可：

- 修改 `package.json`，新增编译任务

```javascript
"build:stage": "vue-cli-service build --mode staging",

```

新增编辑 `.env.staging` 文件：

```yaml
NODE_ENV = development
 
# just a flag
ENV = 'staging'
 
# base api
VUE_APP_BASE_API = '/stage-api'
 
VUE_CLI_BABEL_TRANSPILE_MODULES = true

```

> 使用环境变量：[https://cli.vuejs.org/zh/guide/mode-and-env.html](https://cli.vuejs.org/zh/guide/mode-and-env.html?ref=iiong.com)

这样编译后的 `dist` 文件在控制台可以看到文件源文件，方便变量名打断点调试。不过在调试 `Vue` 程序依然并不满足调试要求，因为无法调试响应式数据。

### Cap4 使用 Vue.js devtools

这东西在大家眼里可能觉得只能在浏览器扩展使用，没想过能在 `Webview` 上使用，在 `Chrome` 或者 `Firefox` 浏览器中，里面扩展程序基本都是网页程序，只要是网页程序，相信有办法可以移植到 `Webview` 使用。

在 [Github vue-devtools](https://github.com/vuejs/vue-devtools?ref=iiong.com) 介绍有段 `Get standalone Electron app (works with any environment!)` 内容吸引了我，虽说只能在 `Electron` 程序使用，但有办法可以在任何程序上使用，故点进去看介绍说明，就有了大概的思路。

在源码 [shell-dev](https://github.com/vuejs/vue-devtools/tree/dev/packages/shell-dev?ref=iiong.com) 使用他编译出几个 `javascript` 文件，注入 `Vue` 程序即可，现在需要解决的就是让它们能在 `file://` 协议中正常运行，在 `shell-dev/src/devtools.js` ：

```javascript
import { initDevTools } from '@front'
import Bridge from '@utils/bridge'
 
const target = document.getElementById('target')
const targetWindow = target.contentWindow
 
// 1. load user app
target.src = 'target.html'
target.onload = () => {
  // 2. init devtools
  initDevTools({
    connect (cb) {
      // 3. called by devtools: inject backend
      inject('./build/backend.js', () => {
        // 4. send back bridge
        cb(new Bridge({
          listen (fn) {
            targetWindow.parent.addEventListener('message', evt => fn(evt.data))
          },
          send (data) {
            console.log('devtools -> backend', data)
            targetWindow.postMessage(data, '*')
          }
        }))
      })
    },
    onReload (reloadFn) {
      target.onload = reloadFn
    }
  })
}
 
function inject (src, done) {
  if (!src || src === 'false') {
    return done()
  }
  const script = target.contentDocument.createElement('script')
  script.src = src
  script.onload = done
  target.contentDocument.body.appendChild(script)
}

```

上述代码的 `inject` 方法会注入失败，查看控制台发现是 `iframe` 通信跨域问题，因为是 `file://` 导致的，所以这边修改成：

```javascript
import { initDevTools } from '@front'
import Bridge from '@utils/bridge'
 
const target = document.getElementById('target')
const targetWindow = target.contentWindow
 
// 1. load user app
target.src = 'target.html'
target.onload = () => {
  // 2. init devtools
  initDevTools({
    connect (cb) {
      // 3. send back bridge
      cb(new Bridge({
        listen (fn) {
          targetWindow.parent.addEventListener('message', evt => fn(evt.data))
        },
        send (data) {
          console.log('devtools -> backend', data)
          targetWindow.postMessage(data, '*')
        }
      }))
    },
    onReload (reloadFn) {
      target.onload = reloadFn
    }
  })
}

```

直接注册 `connect` 方法，然后在 `target.html` 文件手动引入：

```html
<script src="build/backend.js"></script>

```

然后打包文件在 `webview` 测试效果：

![img_1140](https://cdn.iiong.com/2019/12/img_1140.png)

![img_1139](https://cdn.iiong.com/2019/12/img_1139.png)

很显然成功了，这样很方便达到调试程序效果。

### Cap5 后续

在编译 `Vue-Cli` 要做到自动注入上面几个所需要的文件，并且判断编译环境，例如开发环境和生产环境，一般来说生成环境不需要引入 `Vue DevTools` 那几个文件，由于时间仓促，这边暂时没有示例代码，所以有时间再更新博文完善下！