Datasette Apps: 在沙盒环境中托管自定义 HTML 应用程序

概述

Datasette Apps 是自包含的 HTML 和 JavaScript 应用程序,它们在托管于 Datasette 实例上的受限 <iframe> 沙盒中运行。此插件允许开发者创建自定义用户界面和可视化工具,这些工具可以针对 Datasette 数据执行只读 SQL 查询,并通过预配置的存储查询(stored queries)执行写入操作。

这种能力将 Datasette 从一个仅用于提供只读数据的工具转变为一个托管完整读写应用程序的平台,有效地将关系型数据库后端与自包含的 HTML 前端结合在一起。

安全架构:沙盒化与 CSP

Datasette Apps 的主要技术挑战是在可能包含敏感、已认证数据的域名上运行不受信任的 HTML 和 JavaScript。该插件采用了深度防御策略,以防止数据外泄和未经授权的访问。

Iframe 沙盒化

应用程序使用 <iframe sandbox="allow-scripts allow-forms" srcdoc="..."> 进行渲染。此配置确保了沙盒化的应用程序无法:

  • 访问父应用程序的 DOM。
  • 读取或写入 cookie。
  • 访问 localStorage 或其他浏览器机密信息。

内容安全策略 (CSP)

为了防止恶意应用程序使用 fetch() 将私有数据发送到外部服务器,Datasette Apps 通过 <meta http-equiv="Content-Security-Policy"> 标头注入严格的内容安全策略 (CSP)。该策略配置如下:

default-src 'none'; script-src 'unsafe-inline'; style-src 'unsafe-inline'; img-src data: blob:;

一旦设置,此 CSP 策略对于 frame 的内容是不可变的,从而防止 JavaScript 移除或更新标头以绕过限制。

通过 MessageChannel 进行安全通信

为了在不损害安全性的前提下允许应用程序执行有用的工作,该插件使用基于 MessageChannel() 的传输机制来实现 iframe 与父窗口之间的通信。相比于 postMessage(),这种方式更受青睐,因为如果页面发生跳转,MessageChannel() 会自动关闭,从而降低了从不受信任的外部页面执行命令的风险。

数据交互与写入操作

只读 SQL 查询

应用程序可以使用 JavaScript 针对白名单数据库运行只读 SQL 查询。父窗口会在执行查询并将结果返回给应用程序之前验证目标数据库。

受控写入操作

为了在不暴露数据库以进行任意 SQL 注入或恶意更新的情况下启用写入功能,Datasette Apps 利用了存储查询(在 Datasette 1.0a31 中引入)。

管理员不再允许原始 SQL 写入,而是创建特定的存储写入查询(例如,一个 add_todo 查询)。应用程序随后通过名称和特定参数调用这些查询:

const result = await datasette.storedQuery("todos", "add_todo", {
  title: "Buy milk",
  due_date: "2026-06-20",
  priority: "high",
  completed: false
});

AI 驱动的开发工作流

虽然 datasette-apps 插件并不依赖于 LLM,但其架构针对 AI 生成进行了优化。由于应用程序是单文件 HTML 文档,它们是现代 LLM 的理想输出格式。

  • 提示词集成: “创建应用”表单提供了一个包含数据库模式(schema)的可复制提示词,用户可以将其粘贴到 LLM 中,以生成应用程序完整的 HTML/JS 代码。
  • Datasette Agent 集成: 当与 Datasette Agent 一起使用时,AI 助手可以直接使用 app_create 等工具来创建和编辑应用程序,这反映了 Claude 等工具中看到的 “Artifacts” 模式。

社区见解与观点

开发者之间的讨论表明,“BYO UI”(自带 UI)模式正在成为数据驱动型应用程序的新标准,即从固定的 SaaS 仪表板转向灵活的、由 Agent 生成的界面。

“我感觉,如果说因为编程 Agent 的出现导致基于数据库的固定 UI 式 SaaS 应用已死,那么这意味着仅仅是固定仪表板模式已死,而不是 SaaS 本身,而 BYO UI 是新时代的基本门槛。”

其他用户也注意到了将应用程序逻辑和数据保存在一处的实用性,尽管一些人对如果 Agent 在创建这些应用时拥有过多的自主权,可能会导致代码库中出现“AI 垃圾内容(AI slop)”的可能性表示了担忧。

Sources