从零撸了一个 HTML 实体编解码工具,顺便聊聊我和 AI 结对编程的日常

最近在做一个内部项目,需要频繁地把用户输入的内容转成 HTML 实体,再塞进模板里渲染。一开始我都是打开浏览器控制台,手写几行 replace 搞定,但用着用着发现几个痛点:

  • 特殊字符一多,正则写得跟天书似的,回头自己都看不懂
  • 解码的时候用 innerHTML 直接塞,遇到 </textarea> 这种字面量直接翻车
  • 每次都要打开 DevTools,复制粘贴,效率属实拉胯

于是想着,干脆做一个在线小工具,一劳永逸。反正就是个单页面,纯前端,不涉及后端,正好也试试最近很火的 AI 辅助编程到底靠不靠谱。

需求拆解:别一上来就写代码

跟 AI 协作的第一步,不是让它写代码,而是把需求想清楚。我花了几分钟把功能列了个清单:

  1. 编码:<>&"' 转成 &lt; 这种实体
  2. 解码:反向操作,把实体还原成字符
  3. 实时转换:输入即输出,不用点按钮
  4. 全量编码:把非 ASCII 字符全转成 &#xxx; 数字实体
  5. 辅助功能:复制、交换、清空、下载

这个清单看着简单,但里面有几个坑,后面跟 AI 对线的时候全踩了一遍。

第一轮对话:AI 的第一版代码,问题不大但全是细节

我把需求用自然语言描述给 Claude,让它生成一个单文件 HTML。第一版代码框架是对的,UI 布局、事件绑定、i18n 机制都有了,但细看之下有几个问题:

问题一:解码逻辑用 innerHTML 整段塞

AI 第一版是这么写的:

javascript 复制代码
function decodeHTML(str) {
  const el = document.createElement('div');
  el.innerHTML = str;
  return el.textContent;
}

看着挺简洁,但有个致命 bug:如果输入是 &lt;/textarea&gt;,浏览器会把它解析成真正的 </textarea>,直接提前结束 RCDATA 元素,后面的内容全丢了。这在实际使用中太常见了------用户粘贴的代码片段里经常有这种字面量。

我让 AI 改成逐个实体解析,用正则匹配 &...; 再单独解码。AI 改完的版本是这样的:

javascript 复制代码
function decodeHTML(str) {
  return str.replace(/&(#\d+|#[xX][0-9a-fA-F]+|[a-zA-Z][a-zA-Z0-9]*);/g, (m, body) => {
    if (body[0] === '#') {
      const cp = (body[1] === 'x' || body[1] === 'X') ? parseInt(body.slice(2), 16) : parseInt(body.slice(1), 10);
      if (!Number.isFinite(cp) || cp < 0 || cp > 0x10FFFF || (cp >= 0xD800 && cp <= 0xDFFF)) return m;
      try { return String.fromCodePoint(cp); } catch (e) { return m; }
    }
    return decodeNamedEntity(body);
  });
}

这个版本就好多了,String.fromCodePoint 处理增补平面字符,try/catch 兜底非法码点,0xD800-0xDFFF 过滤代理项。这些细节 AI 自己就考虑到了,省了我不少事。

问题二:全量编码的字符范围搞错了

AI 第一版用的是 /[^\x00-\xFF]/g,把所有非 Latin-1 字符都转义了。但需求里说的是"非 ASCII",应该是 /[^\x00-\x7F]/g。就一个字节的差别,行为完全不同------前者会把 éü 这种也转掉,后者只处理真正的非 ASCII。

我指出来之后,AI 秒懂,改成了 [^\x00-\x7F],还顺手加了个 /u 标志,让字符类按码点匹配,避免 emoji 被拆成两个非法代理项实体。这个细节我一开始都没意识到,AI 主动加的。

第二轮:i18n 和深色模式,AI 的模板功力

工具要发布到线上,面向的可能有海外用户,所以 i18n 和深色模式是硬需求。这块 AI 的模板能力很强,我只需要说"支持中英文切换,URL 参数 ?lang=en 优先,其次浏览器语言",它就给出了完整的方案:

javascript 复制代码
const I18N = {
  zh: { title:"HTML 编码/解码", encode:"编码", decode:"解码", ... },
  en: { title:"HTML Encode/Decode", encode:"Encode", decode:"Decode", ... }
};
function detectLang() {
  const p = new URLSearchParams(location.search);
  if (p.get('lang')==='en') return 'en';
  if (p.get('lang')==='zh') return 'zh';
  return navigator.language.startsWith('zh')?'zh':'en';
}

深色模式更简单,CSS 变量 + prefers-color-scheme 媒体查询,几行代码就搞定。AI 在这种标准化场景下几乎不用返工,一次过。

第三轮:踩坑记录,AI 教我的那些细节

跟 AI 来回对线了四五轮,有几个坑值得记录一下:

坑一:textContentinnerHTML 的边界

编码方向我用的是 replace + 映射表,不涉及 DOM 操作,安全。但解码方向如果图省事用 innerHTML 整段塞,就会踩 RCDATA 的坑。AI 给的逐个解析方案虽然代码多了几行,但稳。

坑二:URL.createObjectURL 要配对释放

下载功能里,AI 写了 setTimeout(()=>URL.revokeObjectURL(url), 0),我当时还问它为什么不能直接 revoke。它解释:如果在 click() 之后立即 revoke,某些浏览器(尤其 Safari)会来不及触发下载。加个 setTimeout 延迟到当前事件循环结束,就稳了。这个细节我服。

坑三:复制功能的降级处理

navigator.clipboard 在非 HTTPS 环境下不可用,AI 加了个降级逻辑:

javascript 复制代码
if(!navigator.clipboard) { setStatus('error', t('copyFail')); return; }

虽然没实现 document.execCommand('copy') 的完整降级,但至少在不可用的时候给了明确提示,不会让用户干点没反应。

最终效果

工具做出来之后,我实际用了一段时间,体验比 DevTools 手敲好太多了。实时转换 + 全量编码 + 一键复制,基本上是无缝的。而且纯前端,数据不出浏览器,隐私上也没负担。

代码量不大,单文件 HTML,CSS 和 JS 全内联,没有外部依赖。整个文件不到 10KB,加载基本是瞬时的。

对 AI 辅助编程的一些感想

这次实践下来,我的感受是:AI 编程不是银弹,但确实能把重复劳动压缩到一个很低的水平。对于这种"需求明确、技术栈固定、没有历史包袱"的小工具,AI 的产出质量相当高,我只需要在关键决策点(比如解码逻辑用哪种方案)把把关。

但 AI 也不是万能的------它第一次给出的解码方案就有 RCDATA 的 bug,全量编码的字符范围也搞错过。所以我的工作流是:

  1. 自己先想清楚需求和边界条件
  2. 用自然语言把需求描述给 AI,让它生成初版
  3. 逐条对照需求检查代码,发现问题就反馈给 AI 让它改
  4. 对关键逻辑(安全、边界)自己过一遍,不依赖 AI 的"自觉"

这个流程跑下来,效率确实比纯手写高,质量也有保障。

在线体验

如果你也有类似的 HTML 实体转换需求,可以直接用这个工具:craftvo.app/zh/tool/htm...

支持中英文、深色模式、实时转换、全量编码,所有操作都在浏览器本地完成。源码就是个单文件,想魔改也很方便。

相关推荐
樊小肆19 分钟前
DeepSeeker-Code源码导读12-Hooks四引擎
前端·人工智能·agent
xm_xm_xm_123 分钟前
TypeScript 7 个 核心特性
前端·typescript
pppiii30 分钟前
前端并发请求控制:5 种实现方案完整梳理
前端
郑州光合科技余经理1 小时前
本地生活平台搭建:统一订单表与多后台切换怎么拆
java·开发语言·前端·系统架构·uni-app·php·ai编程
iFlyCai1 小时前
深入理解Flutter:StatefulWidget生命周期全解析(四)
前端·javascript·flutter
xm_xm_xm_12 小时前
Vue 3 项目开发常用操作详细汇总
前端·vue.js
计算机魔术师2 小时前
我国日均词元调用量突破 500 万亿,中国大模型稳居全球第一梯队
前端
码视野2 小时前
基于 Spring Boot + Vue3 的【高校化学实验室安全准入考试与危化品配伍排查系统】设计与实现(含PRD/三端高保真源码/大屏)
前端·人工智能·spring boot·后端·安全·vue3
玄魂2 小时前
VisActor 全新图可视化开源项目:VGraph
前端·数据可视化