更新记录

1.1.0(2025-11-25) 下载此版本

[1.1.0] - 2025-11-25

新增

  • ✨ 新增 stop() 方法 - 停止页面加载(对齐官方 web-view)
  • ✨ 新增 getContentHeight() 方法 - 获取网页内容实际高度(对齐官方 web-view)
  • ✨ 新增 loadData() 方法 - loadHtml的别名,兼容官方 web-view 命名
  • ✨ 新增滚动条控制 - horizontalScrollBarAccess, verticalScrollBarAccess(对齐官方)
  • ✨ 新增 bounces 属性 - iOS 回弹效果控制(对齐官方)

优化

1.0.1(2025-10-28) 下载此版本

[1.0.1] - 2025-10-28

优化

1.0.0(2025-10-28) 下载此版本

更新日志 v1.0.0 初始版本发布

支持基本WebView功能

支持JS桥接通信

支持文件下载

支持进度条显示

查看更多

平台兼容性

uni-app(3.6.14)

Vue2 Vue3 Chrome Safari app-vue app-vue插件版本 app-nvue app-nvue插件版本 Android Android插件版本 iOS iOS插件版本 鸿蒙
- - - - 1.1.0 1.1.0 5.0 1.1.0 12 1.1.0 -
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 快应用-华为 快应用-联盟
- - - - - - - - - - -

uni-app x(3.6.14)

Chrome Safari Android Android插件版本 iOS iOS插件版本 鸿蒙 微信小程序
- - 5.0 1.1.0 12 1.1.0 - -

其他

多语言 暗黑模式 宽屏模式

HyWebView 增强版WebView插件

功能强大的增强版WebView插件,基于UTS开发,提供原生级性能和丰富的功能支持

✨ 特性

  • 🎨 自定义进度条 - 支持自定义颜色和样式的页面加载进度条
  • 🔄 双向JS通信 - 原生与Web页面之间的双向消息传递
  • 📥 增强文件下载 - 内置文件下载,支持自定义目录和网络类型控制
  • 🎯 自定义UserAgent - 灵活设置UserAgent标识
  • 💾 缓存控制 - 完整的缓存管理功能
  • 🧭 页面导航 - 前进、后退、刷新、停止等完整导航支持
  • 🔍 缩放控制 - 可配置的页面缩放功能
  • 📏 内容高度获取 - 实时获取网页内容实际高度
  • 📱 跨平台支持 - 完美支持Android和iOS平台
  • 高性能 - 基于原生WebView,性能卓越
  • 🛡️ 类型安全 - 完整的UTS类型定义和枚举支持
  • 🔒 参数校验 - 严格的参数验证,防止常见错误
  • 📝 详细日志 - 统一的日志前缀,便于调试和问题排查

🆚 与官方 web-view 的区别

核心定位

  • 官方 web-view:标准组件,开箱即用,适合通用场景
  • HyWebView:增强插件,功能强大,适合高级需求

主要差异

功能特性 官方 web-view HyWebView 说明
基础展示 功能相同
JS通信 功能相同
停止加载 v1.1.0 已对齐
获取内容高度 v1.1.0 已对齐
滚动条控制 v1.1.0 已对齐
Bounces(iOS) v1.1.0 已对齐
自定义 UserAgent HyWebView 独有
自定义请求头 HyWebView 独有
完整缓存控制 部分 HyWebView 更强
精细下载控制 基础 HyWebView 更强
页面缩放控制 HyWebView 独有
使用方式 组件标签 原生插件 不同方式

使用场景建议

适合使用官方 web-view

  • ✅ 简单的网页展示(新闻、文章、帮助文档)
  • ✅ 不需要用户登录的页面
  • ✅ 快速开发,省时省力
  • ✅ 与其他组件配合使用

适合使用 HyWebView

  • ⭐ 需要用户认证的页面(个人中心、会员系统)
  • ⭐ 需要自定义浏览器标识的场景
  • ⭐ 企业内部应用(OA、CRM等)
  • ⭐ 需要精细控制缓存和下载
  • ⭐ 混合开发应用

典型应用案例

案例1:新闻App

// 普通资讯页面 → 使用官方 web-view(组件方式)
<web-view src="https://news.example.com"></web-view>

// 会员中心页面 → 使用 HyWebView(带Token登录)
const webView = uni.requireNativePlugin('hy-webview')
webView.create({
  url: 'https://member.example.com',
  headers: {
    'Authorization': 'Bearer ' + userToken
  }
}, handleEvent)

案例2:企业OA系统

// 所有页面都使用 HyWebView
// 原因:需要统一的身份认证和自定义UA识别
const webView = uni.requireNativePlugin('hy-webview')
webView.create({
  url: 'https://oa.company.com',
  userAgent: 'CompanyApp/2.0',
  headers: {
    'X-App-Token': appToken,
    'X-User-ID': userId
  }
}, handleEvent)

核心优势对比

HyWebView 的独有能力

  1. 自定义 UserAgent 🎯

    // 让服务器识别是从App访问
    userAgent: 'MyApp/1.0.0 (iPhone; iOS 16.0)'
  2. 自定义请求头 🔐

    // 自动带上登录令牌,无需重复登录
    headers: {
     'Authorization': 'Bearer xxx',
     'X-Custom-Header': 'value'
    }
  3. 完整缓存控制 💾

    // 用户登出时一键清空
    webView.clearCache(true)
    webView.clearHistory()
  4. 精细下载控制 📥

    // 只在WiFi下载,自定义保存位置
    webView.downloadFile({
     url: 'https://example.com/file.pdf',
     allowMobileNetwork: false,
     directory: 'Documents'
    })

兼容性说明

完全兼容

  • HyWebView 与官方 web-view 可以在同一项目中共存
  • 根据不同页面需求灵活选择
  • 互不冲突,各取所长

�🚀 快速开始

基础用法

<template>
  <view class="container">
    <view :id="webviewId" style="width: 100%; height: 100%;"></view>
  </view>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue'

const webviewId = ref('hyWebview')
let hyWebView = null

onMounted(() => {
  // 根据平台自动选择实现
  const platform = uni.getSystemInfoSync().platform

  if (platform === 'android') {
    hyWebView = uni.requireNativePlugin('hy-webview')
  } else if (platform === 'ios') {
    hyWebView = uni.requireNativePlugin('hy-webview')
  } else {
    console.warn('当前平台不支持hy-webview')
    return
  }

  initWebView()
})

function initWebView() {
  const options = {
    url: 'https://www.example.com',
    showProgress: true,
    progressColor: '#007AFF',
    enableCache: true,
    enableJavaScript: true,
    enableDomStorage: true,
    enableZoom: false
  }

  const success = hyWebView.create(options, handleWebViewEvent)

  if (success) {
    console.log('WebView创建成功')
  }
}

function handleWebViewEvent(event) {
  console.log('WebView事件:', event)

  switch (event.type) {
    case 'pageStart':
      console.log('页面开始加载')
      break
    case 'pageFinish':
      console.log('页面加载完成:', event.data.url)
      break
    case 'progressChanged':
      console.log('加载进度:', event.data.progress + '%')
      break
    case 'error':
      console.error('加载错误:', event.data.error)
      break
    case 'jsMessage':
      console.log('收到JS消息:', event.data)
      handleJsMessage(event.data)
      break
    case 'downloadStart':
      console.log('开始下载:', event.data)
      break
  }
}

function handleJsMessage(data) {
  // 处理来自Web页面的消息
  if (data.method === 'getUserInfo') {
    // 回传数据到Web页面
    hyWebView.postMessage({
      method: 'getUserInfoCallback',
      params: {
        name: '用户名',
        id: '123456'
      },
      callbackId: data.callbackId
    })
  }
}

onUnmounted(() => {
  // 清理资源
  if (hyWebView) {
    hyWebView.destroy()
  }
})
</script>

<style scoped>
.container {
  width: 100%;
  height: 100%;
}
</style>

📖 API文档

create(options, callback)

创建WebView实例

参数:

参数 类型 必填 说明
options HyWebViewOptions WebView配置选项
callback Function 事件回调函数

返回值: boolean - 创建是否成功

HyWebViewOptions 配置项:

// UTS 类型定义
interface HyWebViewOptions {
  url: string                      // 要加载的URL地址
  showProgress?: boolean           // 是否显示进度条,默认false
  progressColor?: string           // 进度条颜色,支持hex颜色值,默认#007AFF
  enableCache?: boolean            // 是否启用缓存,默认false
  userAgent?: string               // 自定义UserAgent
  headers?: any                    // 自定义请求头
  enableZoom?: boolean             // 是否支持缩放,默认false
  enableJavaScript?: boolean       // 是否启用JavaScript,默认true
  enableDomStorage?: boolean       // 是否启用DOM存储,默认true
  horizontalScrollBarAccess?: boolean  // 是否显示横向滚动条,默认true (v1.1.0+)
  verticalScrollBarAccess?: boolean    // 是否显示竖向滚动条,默认true (v1.1.0+)
  bounces?: boolean                    // 是否启用回弹效果(iOS),默认true (v1.1.0+)
}

loadUrl(url)

加载新的URL

参数:

  • url (string): 要加载的URL地址

返回值: boolean - 是否成功

示例:

hyWebView.loadUrl('https://www.example.com')

loadHtml(options) / loadData(options)

加载HTML内容(loadData为loadHtml的别名,兼容官方命名)

参数:

// UTS 类型定义
interface LoadHtmlOptions {
  html: string      // HTML内容
  baseUrl?: string  // 基础URL,用于解析相对路径
  mimeType?: string // MIME类型,默认'text/html'
  encoding?: string // 编码,默认'UTF-8'
  // 兼容官方loadData命名 (v1.1.0+)
  data?: string     // 同html
  baseURL?: string  // 同baseUrl
}

返回值: boolean - 是否成功

示例:

hyWebView.loadHtml({
  html: '<html><body><h1>Hello World</h1></body></html>',
  baseUrl: 'https://www.example.com',
  mimeType: 'text/html',
  encoding: 'UTF-8'
})

evaluateJavaScript(script, callback)

执行JavaScript代码

参数:

  • script (string): 要执行的JavaScript代码
  • callback (Function, 可选): 执行结果回调

示例:

hyWebView.evaluateJavaScript('document.title', (result) => {
  console.log('页面标题:', result)
})

postMessage(data)

向Web页面发送消息

参数:

interface JsBridgeData {
  method: string     // 方法名
  params?: any       // 参数
  callbackId?: string // 回调ID
}

返回值: boolean - 是否成功

示例:

hyWebView.postMessage({
  method: 'updateData',
  params: { key: 'value' },
  callbackId: 'callback_123'
})

reload()

重新加载当前页面

返回值: boolean - 是否成功

stop()

停止当前页面加载

返回值: boolean - 是否成功

示例:

hyWebView.stop()

goBack()

后退到上一页

返回值: boolean - 是否成功

goForward()

前进到下一页

返回值: boolean - 是否成功

canGoBack()

是否可以后退

返回值: boolean

canGoForward()

是否可以前进

返回值: boolean

getUrl()

获取当前页面URL

返回值: string - 当前URL

getTitle()

获取当前页面标题

返回值: string - 页面标题

getContentHeight()

获取网页内容的实际高度

返回值: number - 内容高度(像素)

示例:

const height = hyWebView.getContentHeight()
console.log('内容高度:', height)

注意:

  • Android: 返回的是转换后的像素值
  • iOS: 返回 scrollView.contentSize.height

downloadFile(info)

下载文件

参数:

// UTS 类型定义
interface DownloadInfo {
  url: string                    // 下载URL(必填)
  fileName?: string              // 文件名,不提供则从URL提取
  description?: string           // 下载描述
  allowMobileNetwork?: boolean   // 是否允许移动网络下载,默认true(v1.0.2+)
  directory?: string             // 下载目录,默认系统下载目录(v1.0.2+)
}

返回值: boolean - 是否成功

示例:

// 基础用法
hyWebView.downloadFile({
  url: 'https://example.com/file.pdf',
  fileName: 'document.pdf',
  description: '下载文档'
})

// v1.0.2+ 增强用法
hyWebView.downloadFile({
  url: 'https://example.com/large-file.zip',
  fileName: 'app-data.zip',
  description: '下载应用数据',
  allowMobileNetwork: false,  // 仅WiFi下载
  directory: 'Documents'      // 保存到Documents目录
})

clearCache(includeDiskFiles)

清除缓存

参数:

  • includeDiskFiles (boolean, 可选): 是否包含磁盘文件,默认true

clearHistory()

清除浏览历史记录

destroy()

销毁WebView,释放资源

注意: 组件销毁时务必调用此方法

getView()

获取原生视图对象(供原生渲染使用)

返回值: 原生视图对象

🔗 JS桥接通信

Web页面中的使用

在Web页面中,通过 HyJSBridge 对象与原生通信:

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>WebView Demo</title>
</head>
<body>
  <button onclick="sendToNative()">发送消息到原生</button>

  <script>
    // 发送消息到原生
    function sendToNative() {
      HyJSBridge.postMessage({
        method: 'getUserInfo',
        params: { userId: '123' },
        callbackId: 'callback_' + Date.now()
      })
    }

    // 接收来自原生的消息
    HyJSBridge.onMessage = function(data) {
      console.log('收到原生消息:', data)

      if (data.method === 'getUserInfoCallback') {
        console.log('用户信息:', data.params)
        // 处理用户信息
      }
    }

    // 也可以通过事件监听
    window.addEventListener('hybridMessage', function(event) {
      console.log('收到原生消息:', event.detail)
    })
  </script>
</body>
</html>

通信流程示例

Web → Native:

// Web页面
HyJSBridge.postMessage({
  method: 'login',
  params: { username: 'user', password: 'pass' }
})

// Native处理
function handleWebViewEvent(event) {
  if (event.type === 'jsMessage') {
    if (event.data.method === 'login') {
      // 执行登录逻辑
      doLogin(event.data.params)
    }
  }
}

Native → Web:

// Native发送
hyWebView.postMessage({
  method: 'updateUserInfo',
  params: { name: '张三', avatar: 'http://...' }
})

// Web页面接收
HyJSBridge.onMessage = function(data) {
  if (data.method === 'updateUserInfo') {
    // 更新UI
    updateUI(data.params)
  }
}

⚙️ 配置说明

manifest.json 权限配置

Android平台:

"app-plus": {
  "distribute": {
    "android": {
      "permissions": [
        "<uses-permission android:name=\"android.permission.INTERNET\"/>",
        "<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>",
        "<uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\"/>"
      ]
    }
  }
}

iOS平台:

"app-plus": {
  "distribute": {
    "ios": {
      "capabilities": {
        "entitlements": {
          "com.apple.security.network.client": true
        }
      }
    }
  }
}

📋 事件类型

事件类型 说明 事件数据
pageStart 页面开始加载 { timestamp: number }
pageFinish 页面加载完成 { url: string, timestamp: number }
progressChanged 加载进度变化 { progress: number }
error 加载错误 { error: string, errorCode?: number }
jsMessage JS发送的消息 JsBridgeData
downloadStart 开始下载文件 { url, userAgent, contentDisposition, mimeType, contentLength }

❓ 常见问题

1. WebView无法显示?

原因: 可能是权限配置不正确或网络问题

解决方法:

  • 检查manifest.json中的网络权限配置
  • 确保URL地址正确且可访问
  • 检查是否在真机上测试(部分功能不支持模拟器)

2. JS通信不工作?

原因: JavaScript未启用或桥接未正确初始化

解决方法:

  • 确保 enableJavaScript 设置为 true
  • 等待 pageFinish 事件后再进行通信
  • 检查Web页面中是否正确使用了 HyJSBridge 对象

3. 页面加载慢?

解决方法:

  • 启用缓存: enableCache: true
  • 检查网络环境
  • 优化Web页面资源大小

4. 文件下载失败?

原因: 缺少存储权限或URL不正确

解决方法:

  • Android: 确保添加了存储权限
  • 检查下载URL是否有效
  • 确保文件名不包含特殊字符

5. 如何在页面销毁时清理资源?

onUnmounted(() => {
  if (hyWebView) {
    hyWebView.destroy()
    hyWebView = null
  }
})

6. 支持HTTPS吗?

是的,完全支持HTTPS。对于自签名证书,可能需要额外配置。

7. 可以加载本地HTML文件吗?

可以,使用 loadHtml() 方法加载本地HTML内容:

hyWebView.loadHtml({
  html: localHtmlContent,
  baseUrl: 'file:///android_asset/'
})

💡 最佳实践

1. 资源管理

// 组件中使用
let hyWebView = null

onMounted(() => {
  hyWebView = createWebView()
})

onUnmounted(() => {
  if (hyWebView) {
    hyWebView.destroy()
    hyWebView = null
  }
})

2. 错误处理

function handleWebViewEvent(event) {
  if (event.type === 'error') {
    uni.showToast({
      title: '页面加载失败',
      icon: 'none'
    })
    // 重试或加载备用页面
    hyWebView.loadUrl(fallbackUrl)
  }
}

3. 进度提示

const loading = ref(false)

function handleWebViewEvent(event) {
  switch (event.type) {
    case 'pageStart':
      loading.value = true
      break
    case 'pageFinish':
      loading.value = false
      break
  }
}

4. 消息队列

// 等待页面加载完成后再发送消息
let messageQueue = []
let pageLoaded = false

function handleWebViewEvent(event) {
  if (event.type === 'pageFinish') {
    pageLoaded = true
    // 发送队列中的消息
    messageQueue.forEach(msg => {
      hyWebView.postMessage(msg)
    })
    messageQueue = []
  }
}

function sendMessage(data) {
  if (pageLoaded) {
    hyWebView.postMessage(data)
  } else {
    messageQueue.push(data)
  }
}

⭐ 支持

如果这个插件对你有帮助,请给个star ⭐️

隐私、权限声明

1. 本插件需要申请的系统权限列表:

Android需要网络访问、存储权限;iOS需要网络访问权限

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

许可协议

MIT License

Copyright (c) 2025 HyWebView Contributors

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

暂无用户评论。