Simon Willison's Weblog

Datasette Apps: Host custom HTML applications inside Datasette

8.5内容质量
Datasette Apps: Host custom HTML applications inside Datasette

TL;DR · AI 摘要

Datasette Apps 允许在 Datasette 中运行自定义 HTML 应用,通过沙箱机制保障安全,同时提供强大功能。

核心要点

  • Datasette Apps 使用 <iframe sandbox> 技术实现安全隔离,限制访问 cookies 和 localStorage。
  • 应用可通过 JavaScript 执行只读或配置后的写入 SQL 查询,与 Datasette 数据交互。
  • Datasette Apps 是 Datasette Agent 项目的一部分,旨在提升 HTML 工具与数据库的集成能力。

结构提纲

按章节快速跳转。

  1. 介绍 Datasette Apps 的发布背景及其在 Datasette 生态中的意义。

  2. Datasette Apps 是运行在 Datasette 中的自定义 HTML 应用,通过 iframe 沙箱实现安全隔离。

  3. 应用运行在 iframe 沙箱中,限制访问 cookies、localStorage 和外部 HTTP 请求。

  4. Datasette Apps 提供了 HTML 前端与 Datasette 后端的强结合,提升开发效率和功能灵活性。

  5. Datasette Apps 的灵感来源于早期 Datasette 项目中 HTML 工具与数据库的结合实验。

  6. 通过 iframe sandbox 和 meta 标签等技术,实现 HTML 应用与 Datasette 数据的高效交互。

思维导图

用一张图看清主题之间的关系。

查看大纲文本(无障碍 / 无 JS 友好)
  • Datasette Apps
    • 核心机制
      • iframe 沙箱
      • 限制访问 cookies 和 localStorage
      • CSP 头部注入
    • 创新点
      • HTML 应用与 Datasette 数据交互
      • SQL 查询支持
    • 应用场景
      • 自定义 HTML 工具
      • Datasette Agent 集成

金句 / Highlights

值得收藏与分享的关键句。

  • Datasette Apps 使用 <iframe sandbox="allow-scripts allow-forms"> 技术,限制应用访问 cookies 和 localStorage。

    第 3 段

    ⬇︎ 下载 PNG𝕏 分享到 X
  • Datasette Apps 是 Datasette Agent 项目的一部分,旨在提升 HTML 工具与数据库的集成能力。

    第 4 段

    ⬇︎ 下载 PNG𝕏 分享到 X
  • 应用可通过 JavaScript 执行只读或配置后的写入 SQL 查询,与 Datasette 数据交互。

    第 2 段

    ⬇︎ 下载 PNG𝕏 分享到 X
#Datasette#HTML#JavaScript#iframe#SQL
打开原文

Datasette 应用:在 Datasette 中托管自定义 HTML 应用

Simon Willison 的博客

订阅

#smallhead

由以下公司赞助:

微软 —— 代理项目在演示和生产之间停滞。微软的 MVP 检查清单填补了这一空白。

尝试一下

Datasette 应用:在 Datasette 中托管自定义 HTML 应用

2026 年 6 月 18 日

今天,我们为 Datasette 推出了一个新的插件,名为 datasette-apps,并在 Datasette 项目博客上发布了这个发布公告。那篇文章介绍了 Datasette Apps 是什么,但在这里,我想进一步说明为什么我们要推出它。

#### TL;DR

Datasette Apps 是自包含的 HTML+JavaScript 应用程序,它们运行在 Datasette 应用程序上的一个严格限制的 <iframe> 沙箱中。它们可以使用 JavaScript 对 Datasette 中的数据执行只读 SQL 查询,如果配置了某些预存查询,它们也可以执行写入查询。

这是一个非常简单的示例和一个更复杂的自定义时间线示例——后者看起来像这样:

应用被允许运行 JavaScript 并渲染 HTML 和 CSS。它们在访问方面受到限制——它们运行在 <iframe sandbox="allow-scripts allow-forms"> 中,这阻止它们访问 cookie 或 localStorage,同时它们还注入了 CSP 头(感谢这项研究),这阻止它们向外部主机发出 HTTP 请求,从而防止恶意或有缺陷的应用程序窃取私有数据。

Datasette Apps 最初是我尝试为 Datasette Agent 构建一个 Claude Artifacts 机制的尝试,但很快我意识到,这种沙箱模式对于在界面中添加自定义应用以外的用途也非常有趣,因此我将其提升为 Datasette 生态系统中的一个顶级概念。

它们也是将我多年在 vibe-coded HTML 工具上的实验转化为我主要项目核心功能的一种有趣方式!

你可以通过 GitHub 登录到 agent.datasette.io 的演示实例来尝试 Datasette Apps。

#### 为什么要构建这个?

自首次发布以来,Datasette 一直通过其 JSON API 提供了一个灵活的后端,用于创建自定义 HTML 应用。

我最早的 Datasette 项目之一是在我为 Eventbrite 工作时,为文档构建了一个内部搜索引擎。它的工作原理是通过 cron 定期将不同系统的文档导入 SQLite,然后通过一个 Datasette 实例提供服务,并通过自定义的 HTML+JavaScript 搜索界面直接查询 Datasette API。

我使用客户端 JavaScript 构建 SQL 查询,这最初只是作为一个工程笑话,但结果证明这是一种非常高效的应用迭代方式!

这个项目,加上我在构建 HTML 工具集合方面的经验,以及我对 Claude Artifacts 的实验,让我确信,将 Datasette 风格的后端添加到一个自包含的 HTML 前端中,是一种极其强大的组合。

想象一下,如果 Claude Artifacts 能够访问一个持久的数据库,那将会多么有用。这就是我通过 Datasette Apps 所构建的东西!

#### Datasette 应用中的有趣想法

以下是我构建 Datasette Apps 时发现的一些想法和模式,我认为它们具有持久的影响力。

##### <iframe sandbox="allow-scripts" srcdoc="..."> + <meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src 'unsafe-inline'; style-src 'unsafe-inline'; img-src data: blob:;">

这是使 Datasette Apps 成为可能的关键组合。我需要在一个高度敏感的域上运行不受信任的 HTML 和 JavaScript——一个经过身份验证的 Datasette 实例可能包含各种私有数据。sandbox= 属性让我能够以一种无法与父应用程序交互的方式运行这些不受信任的代码——它无法读取 DOM,也无法访问 Cookie 或从 localStorage 中窃取秘密。但它可以使用 fetch() 和相关方法从其他域加载内容(或窃取数据)。不过,事实证明,如果你在 HTML 页面的开头添加一个 <meta http-equiv="Content-Security-Policy"> 头,你可以设置额外的策略,以限制对其他域的访问。我原本担心恶意 JavaScript 可能能够更新或删除该头,但事实证明这并不成立——一旦设置,CSP 策略对于该帧的内容是不可变的。

##### 使用 postMessage() 和 MessageChannel() 锁定 API

在将这些 iframe 锁定到完全无法执行任何有趣操作的程度后,挑战在于如何重新打开它们,使它们能够运行一个允许列表中的操作,首先是针对指定数据库的只读 SQL 查询。

我最初使用 postMessage() 构建了这个功能的第一个版本,它允许子 iframe 向父窗口发送消息。我创建了一个简单的协议,用于请求父窗口运行 SQL 查询——父窗口可以在执行查询之前验证它是否针对允许列表中的数据库。

其中一个 LLM 工具,我认为是 GPT-5.5,建议如果 iframe 以某种方式从不受信任的域加载了额外的代码,postMessage() 本身可能会被利用。我不认为这适用于 Datasette Apps,但我也相信纵深防御,因此我请 GPT-5.5 帮助我将其迁移到基于 MessageChannel() 的传输方式。

MessageChannel() 的优势在于,如果页面导航到其他地方,通道会自动关闭,从而消除了来自不受信任的外部页面执行命令的可能性。

##### 可见的日志,用于查询和错误

如果你导航到时间线演示并搜索字符串 usercontent,你将获得一些搜索结果,其中嵌入了来自 user-images.githubusercontent.com 域的图像。这个域不在 CSP 允许列表中,因此会触发一个错误。

这些错误会被捕获并传回父帧,可以在有用错误日志中显示。这样做的目的是通过揭示原本不可见的问题,使对应用程序的开发更加高效。

我构建了一个实验,演示你甚至可以将此机制转换为基于什么出错来构建 CSP 允许列表的一键允许机制,但目前我还没有将这个想法集成到 datasette-apps 中。

SQL 查询也会被可见地记录——滚动到时间线页面的底部可以看到这一点。

##### 用于写操作的存储查询

我希望应用程序能够有条件地写入数据库,但这比 SQL 读取更加危险!

我的解决方案涉及 Datasette 的存储查询功能,该功能从“预定义查询”重新品牌,并在最近的 Datasette 1.0a31 版本中进行了重大升级——这项工作直接受到 Datasette Apps 的启发。

用户可以创建一个存储写入查询,执行插入或更新操作,然后将该特定查询添加到允许列表中,供应用程序使用。从应用程序中的代码使用它看起来像这样:

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

我自己才刚刚开始探索这个功能所解锁的可能性,但我的目标是支持构建安全的全读写应用程序,这些应用程序作为 Datasette Apps 来实现。

##### 复制并粘贴提示以构建一个应用程序

Datasette Apps 插件完全不依赖于 LLM(大型语言模型),但这些自包含的应用程序正是现代 LLM 编写时的理想格式。

创建应用程序的表单最后包含一个可复制的提示。这个提示包含了模型构建新应用程序所需的所有信息,包括所选数据库的模式。

这意味着你可以点击“复制”,将其粘贴到 ChatGPT、Claude 或 Gemini 中,告诉模型你的需求,模型有很大可能性会输出构建应用程序所需的代码。

如果你安装了 Datasette Agent,你的 AI 助手也将获得创建新应用程序和编辑现有应用程序的工具,类似于 Claude Artifacts 的方式。

#### 借助大量 AI 助力构建

Datasette Apps 最初于四月份以 datasette-agent-artifacts 的形式出现,之后我将其重命名为 datasette-agent-edit,仅保留其编辑工具。我构建这个插件是作为 Datasette Agent 的第一个插件之一,以帮助将插件钩子调整到合适的形状。该原型最初主要使用 Claude Opus 4.6 在 Claude Code 中构建。

当我转向 Datasette Apps 时,我基于 Codex Desktop 和 GPT-5.5 xhigh 构建了一个计划,这基于广泛的对话,并结合了我之前构建的 datasette-agent-artifacts 和其他原型。

随后的大部分工作都继续使用 Codex,但在我们短暂获得 Claude Fable 5 访问权限的几天里,我让它对产品进行了安全评估(这一能力随后被美国政府禁止),它发现了一个非常严重的问题。

我允许用户为他们的应用程序允许列出 CSP 主机,但 Fable 指出了以下攻击方式:

  • 一个拥有创建应用程序权限但权限较低的用户创建了一个应用程序,该应用程序查询 SQLite 以获取所有可用表,并将所有数据发送到他们通过 CSP 允许列出的主机。
  • 然后他们欺骗一个拥有访问私有数据权限的管理员用户访问他们的应用程序。
  • ……现在,该应用程序可以以该用户身份运行查询并窃取其私有数据!

这显然是不可接受的。我通过限制允许列出任何域的权限到一个新的 apps-set-csp 权限来解决这个问题,这个权限仅限于受信任的员工。网站管理员还可以通过配置 Datasette 的 allowed_csp_origins 列表来设置允许的 CSP 原始地址,普通用户可以选择这些地址。这意味着你可以允许 cdnjs.cloudflare.com,然后你的用户就可以构建从 cdnjs CDN 加载额外 JavaScript 库的应用程序。

我对 Datasette Apps 进行了非常仔细的审查,特别是与安全相关的部分。关键的沙箱和 CSP 配置基于多个 AI 助力的原型和测试。

#### 到目前为止,表现良好

我对这个初始版本非常满意。

Datasette 正在超越其最初作为只读数据服务应用程序的起源,发展成一个更丰富的工具生态系统,用于在数据收集后对数据进行有用的操作。

Datasette 的起源可以追溯到数据新闻领域。我一直对记者获取大量关于世界的数据之后会发生什么这个问题感兴趣。Datasette 支持对这些数据进行探索和发布。Datasette Agent 增加了借助人工智能进行查询的功能。现在,Datasette Apps 将这一功能扩展到构建自定义的界面和可视化工具,以帮助揭示隐藏在数据中的故事。

发布于 2026 年 6 月 18 日晚 11:58 · 关注我

Mastodon

,

Bluesky

Twitter

订阅我的电子报

更近的文章

  • GLM-5.2 可能是目前最强大的纯文本开源权重 LLM - 2026 年 6 月 17 日
  • 将 WASM 轮子发布到 PyPI 以供 Pyodide 使用 - 2026 年 6 月 13 日

#primary

这是 Datasette Apps:由 Simon Willison 于 2026 年 6 月 18 日发布,可在 Datasette 中托管自定义 HTML 应用程序。

iframes

24

javascript

759

projects

538

sandboxing

48

ai

2,080

datasette

1,519

generative-ai

1,837

llms

1,805

ai-assisted-programming

390

content-security-policy

12

上一篇:GLM-5.2 可能是目前最强大的纯文本开源权重 LLM

月度简报

每月赞助我 10 美元,获取本月最重要的 LLM 发展的精选电子邮件摘要。

让我少发点邮件吧!

赞助并订阅

#secondary

#wrapper

  • 披露信息
  • 附录
  • ©
  • 2002
  • 2003
  • 2004
  • 2005
  • 2006
  • 2007
  • 2008
  • 2009
  • 2010
  • 2011
  • 2012
  • 2013
  • 2014
  • 2015
  • 2016
  • 2017
  • 2018
  • 2019
  • 2020
  • 2021
  • 2022
  • 2023
  • 2024
  • 2025
  • 2026