JS API 说明
.js 文件可调用的接口与示例。
.js 文件可以调用一组由应用提供的 JS 接口,用来输出日志、弹窗、读写文件、访问剪贴板、发送网络请求、触发通知和读取设备信息。
#预期效果
WebView 示例会显示一个按钮,点击后写入剪贴板并把读取结果显示在页面里。
#先选 JS 还是 Python
| 需求 | 首选 | 原因 |
|---|---|---|
| HTML 里响应按钮、更新 DOM、展示轻量交互 | JS API | 逻辑离页面最近,回调能直接更新元素。 |
| 原生表单、列表、导航、图表和媒体页面 | appui | 原生控件、状态和可访问性更完整。 |
| 复杂网络请求、鉴权、上传下载、文件批处理 | Python 模块 | 错误处理和数据处理更清晰。 |
| 照片、定位、通知、健康、蓝牙等系统能力 | 原生模块 | 权限、取消和不可用状态有明确约定。 |
| 只嵌入一个静态说明页或预览页 | WebView(html=...) | JS API 可以只用于复制、打开链接和轻提示。 |
#API 分组
| 分组 | API | 用途 |
|---|---|---|
| console | console.log, console.warn, console.error | 日志输出 |
| 弹窗 | alert, confirm, prompt | 短流程阻塞输入 |
| 剪贴板 | getClipboard, setClipboard | 读取和写入文本 |
| 存储 | localStorage | 小型持久键值状态 |
| 网络 | fetch | HTTP GET 辅助函数 |
| 系统 | openURL, openSettings, getDeviceInfo | 系统接口 |
#在 WebView 里使用
如果你要把 HTML 嵌入 AppUI,先用 WebView(html=...) 放入页面,再在 HTML 中调用注入的 JS API。
已复制
import appui
html = """
<button id="copy">复制文本</button>
<p id="status">等待操作</p>
<script>
document.getElementById("copy").addEventListener("click", function() {
setClipboard("来自 WebView")
getClipboard(function(text) {
document.getElementById("status").textContent = text || "剪贴板为空"
})
})
</script>
"""
def body():
return appui.NavigationStack(
appui.WebView(html=html).navigation_title("JS API")
)
appui.run(body)
#写 JS API 的心智模型
- 宿主:JS API 只在应用提供的 WebView 环境里存在。
- 触发:剪贴板、通知、打开 URL、文件写入等能力由点击或明确动作触发。
- 回调:多数系统能力是回调式 API,先更新 DOM,再记录必要日志。
- 数据:小状态用
localStorage,复杂数据和敏感数据交给 Python 模块。 - 边界:WebView 负责展示和轻交互,业务流程由 AppUI 或 Python 承载。
#console 输出
已复制
console.log("Hello")
console.warn("警告")
console.error("错误信息")
#alert / confirm / prompt
已复制
alert("提示")
confirm("确定吗?", function(ok) {
console.log(ok)
})
prompt("请输入", "默认", function(text) {
console.log(text)
})
#剪贴板
已复制
getClipboard(function(text) {
console.log(text)
})
setClipboard("复制的内容")
#localStorage
已复制
localStorage.setItem("key", "value")
var value = localStorage.getItem("key")
localStorage.removeItem("key")
#文件读写
已复制
readFile("a.txt", function(err, content) {
console.log(err || content)
})
writeFile("b.txt", "内容", function(err) {
console.log(err || "ok")
})
listDir(".", function(err, jsonText) {
console.log(err || JSON.parse(jsonText))
})
#fetch 网络请求
已复制
fetch("https://httpbin.org/get")
.then(function(body) {
console.log(body)
})
.catch(function(err) {
console.error(err)
})
#通知
已复制
requestNotificationPermission(function(granted) {
if (granted) {
scheduleNotification("标题", "内容", 3)
}
})
#设备与系统
已复制
console.log(getBatteryLevel(), isCharging())
console.log(getDeviceInfo())
openURL("https://apple.com")
openSettings()
#常用工具
已复制
vibrate("light")
var now = getCurrentTime()
console.log(formatDate(now, "yyyy-MM-dd HH:mm"))
console.log(hash("hello", "sha256"))
qrcode("https://www.python.org", function(err, base64) {
console.log(err || base64)
})
#定时器
已复制
var timer = setTimeout(function() {
console.log("1 秒后")
}, 1000)
var interval = setInterval(function() {
console.log("每 2 秒")
}, 2000)
clearTimeout(timer)
clearInterval(interval)
#截图和加载提示
已复制
showLoading("处理中...")
takeScreenshot(function(err, base64) {
hideLoading()
console.log(err ? err : "base64 长度:" + base64.length)
})
#失败路径
| 情况 | 应该怎么处理 |
|---|---|
| API 未定义 | 确认代码运行在应用提供的 WebView 环境里,而不是普通外部浏览器。 |
| 回调没有触发 | 把结果写到页面元素或 console,先确认按钮事件已绑定。 |
| 文件或通知失败 | 检查用户动作、权限和文件路径;失败时显示简短错误。 |
| 请求复杂接口 | 复杂 HTTP、鉴权和上传流程优先交给 Python network 模块。 |
#发布前检查
| 检查项 | 合格标准 |
|---|---|
| 环境 | 页面在 AppUI WebView 中运行,不依赖外部浏览器注入 API。 |
| 触发 | 剪贴板、通知、打开 URL 和文件写入由用户点击触发。 |
| 回调 | 成功、取消和失败都更新页面元素,不只写 console。 |
| 数据 | secret 不放进 localStorage,复杂数据交给 Python 保存。 |
| 边界 | 复杂 HTTP、权限和原生能力不堆在网页脚本里。 |
#使用规则
- JS API 是应用提供的接口,不等同于浏览器完整 Web API。
- 文件 API 适合读写脚本工作区里的小文件,不适合大文件流式处理。
fetch是轻量 GET 辅助函数;复杂请求优先用 Pythonnetwork模块。- 弹窗、通知、剪贴板这类能力必须由明确用户动作触发。
- 如果页面不需要 DOM,优先使用 Python 原生模块和 AppUI 组件。