用 AI 写网页,
一键打包成 App 从未如此简单

WebCatX 是专为移动设备设计的 Web 编辑器:内置 AI 助手帮你生成与修改代码,还能把网页项目直接打包成可安装的安卓 App,随时随地创作、预览与上线。

用户头像 用户头像 用户头像 用户头像
4.8/5

来自 10,000+ 位开发者的好评

WebCat 应用展示

强大功能,尽在指尖

AI 助手、一键打包 APK、安卓能力桥接,让移动 Web 开发与发布一步到位

AI 助手

内置 AI 助手,能理解你的项目,帮你生成、搜索定位并精确修改代码,移动端也能智能高效地开发。

一键打包 APK

把网页项目直接打包成可安装的安卓 App,自定义包名、图标、权限与版本号,全程在手机本地完成,无需电脑。

CatNative 原生能力

CatNative 是 WebCatX 自研的安卓交互框架。用它制作或打包的 App,页面能像真正的手机软件一样操作手机:读写文件、保存相册与下载、拍照选图、一键分享、申请权限、查看已装应用等,网页从此不再只是网页。

CatNative 文档

window.webcat 的完整 API 参考:文件、媒体、拍照、分享、扫码、录音、网络、页面窗口、共享变量等调用方式。

查看完整文档 →

语法高亮

支持 HTML、CSS、JavaScript 等多种语言的语法高亮,让代码结构清晰易读。

实时预览

编辑代码的同时实时预览效果,支持多设备视图模拟,所见即所得。

共享空间

支持上传源码分享给其他用户,或下载其他用户分享的源码资源。

界面预览

直观简洁的界面设计,让移动编码更加高效

WebCat 代码编辑界面

代码编辑界面

专业的代码编辑环境,支持语法高亮和自动缩进

WebCat 项目管理

项目管理

轻松管理多个项目

WebCat 实时预览

共享空间

一键导入其他用户共享的源码

用户怎么说

来自真实用户的使用体验和评价

"作为一名前端开发者,我经常需要在外出时快速修改代码。WebCat 让我能够在手机上高效工作,实时预览功能非常实用!"

用户头像

李明

资深前端工程师

"学生党表示非常好用!在课堂上听老师讲课时,可以直接用手机编写示例代码,云同步功能让我回家后能在电脑上继续学习。"

用户头像

张晓华

计算机专业学生

"作为自由职业者,我需要随时随地响应客户需求。WebCat 的一键导入共享源码功能让我能快速向客户展示效果,大大提高了工作效率。"

用户头像

王建国

全栈自由开发者

常见问题

关于 WebCat 的一些常见疑问解答

立即开始移动编码之旅

下载 WebCat,随时随地编写、预览和分享你的代码,让创意不再受设备限制。

支持 Android 5.0+

CatNative API 文档

CatNative 是 WebCatX 自研的安卓原生桥接框架:项目页面通过全局对象 window.webcat 直接调用安卓能力,预览与打包 APK 均支持,无需引入任何库。以下是 window.webcat 的完整 API 参考。

同步方法直接返回对象;异步方法返回 Promise,用 await 调用。失败时:同步返回 {ok:false,error},异步 Reject(Error.message)。

window.webcat 由原生在页面开始 / 完成时异步注入,可能晚于 load 事件;建议在 DOMContentLoaded / load 之后再调用,若此时仍取不到,请重试或轮询 window.webcat 后再调用。

webcat.fs —— 私有文件(应用私有目录,两端一致)

接口类型入参出参
fs.readFile 读取文件异步path, encoding?('utf8'/'base64'){ok, content}
fs.writeFile 写入文件异步path, content, encoding?{ok, size}(自动建父目录)
fs.list 列出目录异步dir?{ok, items:[{name, isDir, size, modified}]}
fs.delete 删除异步path{ok}(文件 / 空目录)
fs.mkdir 创建目录同步dir{ok}
fs.exists 判断存在同步path{ok, exists, isDir}
fs.stat 文件信息同步path{ok, size, isDir, modified}
fs.readAsset 读取项目文件异步path(项目内相对){ok, content}(打包后只读)
fs.openFile 系统打开文件同步path{ok}
fs.zip 压缩异步source, targetZip(.zip){ok, size}
fs.unzip 解压异步zipPath, outDir{ok, count}
fs.move 移动 / 重命名异步source, target{ok}
fs.copy 复制异步source, target{ok}

webcat.ext —— 公开文件(target = "root" 全授权 / SAF handle)

接口类型入参出参
ext.isFullAccess 是否全授权同步—{ok, granted}
ext.requestFullAccess 开启全授权同步—{ok}(跳本应用设置)
ext.pickDirectory 选择目录异步—{ok, handle}(授权持久化)
ext.revoke 撤销授权同步handle{ok}
ext.list 列出异步target, path?{ok, items}
ext.readFile 读取异步target, path, encoding?{ok, content}
ext.writeFile 写入异步target, path, content, encoding?{ok, size}
ext.delete 删除异步target, path{ok}
ext.mkdir 建目录同步target, path{ok}
ext.exists 存在同步target, path{ok, exists, isDir}
ext.stat 信息同步target, path{ok, size, isDir, modified}
ext.openFile 系统打开同步target, path{ok}
ext.zip 压缩异步target, source, targetZip{ok, size}
ext.unzip 解压异步target, zipPath, outDir{ok, count}
ext.move 移动异步target, source, dst{ok}
ext.copy 复制异步target, source, dst{ok}

target 取 "root"(需“所有文件访问”,path 为绝对路径)或 SAF handle(path 相对授权目录)。

webcat.media —— 媒体保存 / 选择

接口类型入参出参 / 说明
media.saveImage 存相册异步name, data, path?{ok, uri?, path?},默认存 Pictures
media.saveToDownload 存下载异步name, data, path?{ok, uri?, path?},默认存 Download
media.save 自动异步name, data, path?按扩展名自动:图片 → 相册,其它 → Download
media.pickImage 选图异步format?, maxBytes?{ok, name, mime, size, base64 | uri | path}
media.pickFile 选文件异步mime?, format?, maxBytes?同上,mime 默认 */*
  • data 支持:裸 base64 / data:image/png;base64,... / http(s) URL(自动下载)。
  • path:省略 = 默认集合;非 / 开头 = 该集合下子目录(如 myapp/cards);/ 开头 = 绝对路径写文件(需全盘权限)。
  • format 默认 base64;uri 返回 content uri;path 尽力解析本地绝对路径,失败会提示改用 uri / base64。
  • maxBytes 默认 15MB(仅 base64 上限),超限请改用 format=uri。

webcat.camera —— 相机

接口类型入参出参 / 说明
camera.takePhoto异步save?{ok, name, size, base64};调系统相机(免 CAMERA 权限),save=true 同时存相册

webcat.audio —— 音频播放

接口类型入参出参 / 说明
audio.play异步{url | source, path, volume?, seek?}播完 resolve {ok, end:true};本地支持 fs / root / SAF,或 http(s)
audio.stop / pause / resume异步—{ok}
audio.setVolume异步volume(0~1){ok}
audio.seek异步position(ms){ok}
audio.isSupported同步—{ok, supported}

webcat.tts —— 文字转语音(无需权限)

接口类型入参出参 / 说明
tts.isSupported同步—{ok, supported, speaking}
tts.speak异步text, {lang?, rate?, pitch?, volume?, queue?}读完 resolve {ok, end:true};lang 如 "zh-CN";rate / pitch 默认 1;volume 0~1;queue=true 追加不打断
tts.stop异步—{ok} 停止并结束当前朗读
tts.pause异步—{ok} 暂停(系统 TTS 无原生暂停,等价停止)
tts.resume异步—{ok} 从头继续最近一次内容

webcat.record —— 录音(需打包勾选“录音 / 麦克风”)

接口类型入参出参 / 说明
record.start异步{source:'fs'/'root'/handle, path?, format?:'aac'|'amr'}{ok, started, path};缺省 fs records/rec_时间戳.*
record.stop异步—{ok, path, size, durationMs, format}
record.cancel异步—{ok} 丢弃
record.state同步—{ok, recording}

webcat.scan —— 扫码(需打包勾选“相机”)

接口类型入参出参 / 说明
scan.scan异步—{ok, text, format}(实时扫码;预览返回引导)
scan.decodeImage异步{uri | base64 | source, path}{ok, text}
scan.generate同步text, size?{ok, base64} 生成二维码 PNG

webcat.clipboard —— 剪切板(同步)

接口类型入参出参
clipboard.get 读取剪切板同步—{ok, text}
clipboard.set 写入剪切板同步text{ok}

webcat.share —— 分享

接口类型入参出参 / 说明
share.text 分享文本同步text, title?系统分享面板
share.file 分享文件同步source('fs'/'root'/handle), path, mime?fs / root 走 FileProvider

webcat.app —— 应用

接口类型入参出参 / 说明
app.info 应用信息同步—{ok, packageName, versionName, versionCode, appName}
app.quit 退出应用同步—{ok}
app.openFile 系统打开文件同步source('fs'/'root'/handle), path{ok}
app.install 安装同步source, path需允许未知来源;SAF 先复制到 cache
app.openAppSettings同步—跳本应用设置
app.isInstalled同步packageName{ok, installed, appName?, versionName?, limited}(limited = 未勾选“应用列表”,可能误报未安装)
app.listApps异步—需打包勾选 QUERY_ALL_PACKAGES;{ok, apps:[{packageName, appName, versionName, versionCode, isSystem}]}
app.launchPackage同步packageName{ok, launched};按包名打开(勾选“应用列表”更准)
app.openUri同步uri{ok, launched};任意 scheme / url

webcat.permission —— 权限

接口类型入参出参
permission.check 检查权限同步perms: string[]{ok, granted[], denied[], undeclared[]}
permission.request 申请权限异步perms: string[]{ok, granted[], denied[], undeclared[]}

undeclared = 未声明权限(打包时未勾选 / 不支持)→ 应提示“打包时勾选”或“系统授予”。特殊权限 MANAGE 走 ext.requestFullAccess。

webcat.sys —— 系统信息(同步)

接口类型入参出参
sys.info 系统信息同步—{ok, brand, model, androidVersion, sdkInt, screenWidth, screenHeight, density}
sys.network 网络状态同步—{ok, online, type: wifi / mobile / none}
sys.battery 电池同步—{ok, level, charging}

webcat.screen —— 屏幕(同步)

接口类型入参出参 / 说明
screen.keepOn 屏幕常亮同步on窗口 FLAG_KEEP_SCREEN_ON 开 / 关
screen.setOrientation同步modeauto / portrait / landscape / sensor

webcat.phone —— 电话短信(同步,免权限跳系统)

接口类型入参出参
phone.dial 拨号同步number{ok}
phone.sms 发短信同步number, text?{ok}

webcat.qq —— QQ 跳转(同步)

接口类型入参出参
qq.openProfile 打开 QQ 名片同步qq: QQ号{ok, launched}
qq.openGroup 打开 QQ 群同步qq: 群号{ok, launched}

webcat.browser —— 系统浏览器(同步)

接口类型入参出参
browser.open 用浏览器打开网页同步url{ok}

webcat.contacts —— 通讯录

接口类型入参出参 / 说明
contacts.list 读取通讯录异步—{ok, contacts:[{name, phones:[]}]}(需 READ_CONTACTS,打包勾选)

webcat.location —— 定位

接口类型入参出参 / 说明
location.get 获取定位异步—{ok, latitude, longitude, accuracy, provider}(需定位权限,打包勾选)

webcat.download —— 下载

接口类型入参出参 / 说明
download.download 下载文件异步url, source('fs'/'root'/handle), path{ok, path, size}
download.stream 流式下载异步{url, source, path, headers?, onProgress}{ok, path, size};带进度(中间帧 {progress:{loaded, total}})

webcat.network —— 原生网络(无 CORS 限制)

接口类型入参出参 / 说明
network.request异步{method, url, headers, body, timeout?, returnBase64?}{ok, status, body};body 支持 base64: 前缀
network.upload异步{url, method?, headers?, fieldName?, files:[{source:'fs'/'root'/handle, path, name?}], fields?, onProgress}{ok, status, body};multipart,已知路径原生直传

webcat.page —— 页面窗口

接口类型入参出参 / 说明
page.open同步{url | path, params?}{ok};打开新页面窗口(path 相对当前网页根,或 http(s) / file 绝对路径)
page.params同步—本页收到的参数
page.end同步—关闭当前页面

webcat.store —— 会话共享(同步,仅内存,App 退出即清)

接口类型入参出参
store.set同步key, value{ok}
store.get同步key{ok, value}
store.remove同步key{ok}
store.keys同步—{ok, keys[]}

webcat.statusBar —— 状态栏

默认状态下,状态栏 / 底部导航栏由原生自动避让,普通页面无需任何调用,也不要加 padding(会重复留白)。

statusBar.setAdaptive(true) 沉浸时原生不再避让、状态栏覆盖页面;仅当顶部有需要完整显示的内容(标题 / 按钮等)才加 padding,且 height 是设备 px,CSS 要用 height / density。

接口类型入参出参 / 说明
statusBar.setColor同步color, darkIcon?自定义状态栏颜色(#RRGGBB / #AARRGGBB 或整数),导航栏同色;darkIcon 省略时按亮度自动判断
statusBar.setDarkIcon同步darkIcontrue = 深色图标,false = 浅色图标
statusBar.hide同步—隐藏状态栏(导航栏保留;焦点变化后保持隐藏)
statusBar.show同步—显示状态栏
statusBar.setAdaptive同步enabledtrue = 沉浸(原生不再避让),false = 恢复自动避让(默认)。别名 setOverlay
statusBar.height同步—{ok, height, density};height 为设备 px(非 dp),CSS 用 height / density
webcat.statusBar.setAdaptive(true);
const { height, density } = webcat.statusBar.height();
document.querySelector(".app-header").style.paddingTop = (height / density) + "px";

setAdaptive 作用于整个预览 / 打包窗口(含原生顶栏);导航栏颜色始终跟随状态栏。

webcat.ui —— 提示(同步)

接口类型入参出参 / 说明
ui.toast 提示同步msg, long?{ok}
ui.vibrate 震动同步ms{ok};需打包勾选“震动”(VIBRATE)

安全限制

  • 网页不可访问 WebCatX 自身目录(/WebCatX/project、/WebCatX/cache):ext.list 命中返回空列表,其余读 / 写 / 删 / 开 / 分享命中返回“路径受保护,不允许网页访问 WebCatX 目录”;SAF 授权目录不受限。

调用示例

// 私有文件
await webcat.fs.writeFile("data.json", JSON.stringify({a:1}));
const { content } = await webcat.fs.readFile("data.json");

// 压缩 / 解压(私有)
await webcat.fs.zip("js", "backup.zip");
await webcat.fs.unzip("backup.zip", "restore");

// 剪切板 / 系统信息(同步)
const { text } = webcat.clipboard.get();
const info = webcat.sys.info();

// 权限(异步)
const r = await webcat.permission.request(["android.permission.CAMERA"]);
if (r.undeclared.length) { webcat.ui.toast("该权限未在打包时勾选"); }

// 文字转语音
await webcat.tts.speak("你好,这是 WebCatX", { lang: "zh-CN" });

// 外部跳转
webcat.qq.openProfile("123456");
webcat.browser.open("https://example.com");

// 下载到私有目录
await webcat.download.download("https://x.com/a.png", "fs", "img/a.png");

// 通讯录 / 定位
const { contacts } = await webcat.contacts.list();
const loc = await webcat.location.get();

// 公开目录
if (webcat.ext.isFullAccess().granted) {
  await webcat.ext.writeFile("root", "/storage/emulated/0/Download/a.txt", "hi");
} else {
  webcat.ext.requestFullAccess();
}
const { handle } = await webcat.ext.pickDirectory();
await webcat.ext.writeFile(handle, "data.json", "{}");