第35篇:AI生成代码的审核与修正

AI 能帮你写代码,但无法替你承担责任——学会审核和修正 AI 输出,是每位现代前端开发者的必修课。


学习目标

  • 识别 AI 生成 HTML 代码中的常见错误模式
  • 掌握系统化的代码审核流程
  • 学会使用 W3C Validator 等工具验证 AI 输出
  • 建立个人化的 AI 代码审查清单
  • 能够将"AI 初稿"修正为符合最佳实践的生产代码

核心知识点

一、AI 生成 HTML 的典型错误模式

AI 模型在生成 HTML 时,虽然语法通常正确,但在语义化、可访问性和现代最佳实践方面常常出现问题。以下是六大高频错误模式。

1. Div 汤(Div Soup)

AI 倾向于过度使用 <div>,而忽略 HTML5 语义化标签。

AI 原始输出:

<div class="header">
  <div class="logo">我的博客</div>
  <div class="nav">
    <div class="nav-item"><a href="/">首页</a></div>
    <div class="nav-item"><a href="/about">关于</a></div>
  </div>
</div>
<div class="main">
  <div class="article">
    <div class="title">文章标题</div>
    <div class="content">文章内容...</div>
  </div>
</div>
<div class="footer">版权所有</div>

修正后版本:

<header>
  <div class="logo">我的博客</div>
  <nav>
    <ul>
      <li><a href="/">首页</a></li>
      <li><a href="/about">关于</a></li>
    </ul>
  </nav>
</header>

<main>
  <article>
    <h1>文章标题</h1>
    <p>文章内容...</p>
  </article>
</main>

<footer>
  <p>版权所有</p>
</footer>

关键修正点:

原标签 修正为 原因
<div class="header"> <header> 使用语义化结构标签
<div class="nav"> <nav> + <ul> 导航应使用列表结构
<div class="title"> <h1> 标题必须使用标题标签
<div class="main"> <main> 主内容区使用 main 标签
<div class="article"> <article> 独立文章使用 article 标签
<div class="footer"> <footer> 页脚使用 footer 标签
2. 缺失可访问性属性

AI 经常忘记添加 altlabelaria-* 等可访问性属性。

AI 原始输出:

<img src="hero.jpg" width="800" height="400">

<input type="text" placeholder="请输入用户名">
<input type="password" placeholder="请输入密码">
<button>提交</button>

<div class="error">用户名不能为空</div>

修正后版本:

<!-- 添加 alt 描述图片内容 -->
<img src="hero.jpg" alt="夕阳下的海滩风景" width="800" height="400">

<!-- 为每个输入框关联 label -->
<label for="username">用户名</label>
<input type="text" id="username" name="username" placeholder="请输入用户名" required>

<label for="password">密码</label>
<input type="password" id="password" name="password" placeholder="请输入密码" required>

<button type="submit">提交</button>

<!-- 错误提示添加 role 和 aria-live -->
<div class="error" role="alert" aria-live="assertive">
  用户名不能为空
</div>
3. 错误的标签嵌套

AI 有时会写出不符合 HTML 规范的嵌套结构。

AI 原始输出(错误):

<!-- 错误:p 标签内不能嵌套块级元素 -->
<p>
  这是一段文字
  <div>这里是一个 div</div>
  继续文字
</p>

<!-- 错误:a 标签不能嵌套交互元素 -->
<a href="/page">
  <button>点击我</button>
</a>

<!-- 错误:ul 的直接子元素必须是 li -->
<ul>
  <div>
    <li>项目一</li>
  </div>
</ul>

修正后版本:

<!-- 正确:使用 div 包裹,内部使用 p -->
<div>
  <p>这是一段文字</p>
  <div>这里是一个 div</div>
  <p>继续文字</p>
</div>

<!-- 正确:按钮独立使用,或改用其他方案 -->
<button onclick="location.href='/page'">点击我</button>
<!-- 或者 -->
<a href="/page" class="btn-link">点击我</a>

<!-- 正确:ul 的直接子元素必须是 li -->
<ul>
  <li>项目一</li>
</ul>

常见嵌套规则速查:

父元素 禁止嵌套 原因
<p> <div>, <p>, <ul>, <table> p 只能包含行内元素
<a> <a>, <button>, <input> 交互元素不可嵌套
<ul> / <ol> <li> 元素 列表结构要求
<table> 非表格相关标签 表格结构要求
<button> <a>, <button>, <form> 按钮内不可嵌套交互元素
4. 使用过时的标签和属性

部分 AI 模型训练数据包含较旧的 HTML,可能输出已废弃的标签。

AI 原始输出(过时):

<center>居中内容</center>

<font color="red" size="4">红色大字</font>

<table border="1" cellpadding="5" cellspacing="0">
  <tr>
    <td bgcolor="#eee">单元格</td>
  </tr>
</table>

<br>
<br>
<br>

<img src="photo.jpg" border="0">

修正后版本:

<!-- 使用 CSS 替代 center -->
<div style="text-align: center;">居中内容</div>

<!-- 使用 CSS 替代 font -->
<span style="color: red; font-size: 1.25rem;">红色大字</span>

<!-- 使用 CSS 替代表格样式属性 -->
<table class="data-table">
  <tr>
    <td>单元格</td>
  </tr>
</table>

<!-- 使用 CSS margin 控制间距 -->
<div style="margin-top: 3rem;"></div>

<!-- 移除 border 属性,用 CSS 控制 -->
<img src="photo.jpg" alt="描述文字">

已废弃标签/属性对照表:

废弃写法 现代替代方案 说明
<center> CSS text-align: center HTML5 废弃
<font> CSS font-* 属性 HTML5 废弃
<b>, <i>(纯样式) <strong>, <em> 语义化替代
bgcolor CSS background-color 属性废弃
border(img/table) CSS border 属性废弃
cellpadding / cellspacing CSS padding / border-spacing 属性废弃
align CSS text-align / float 属性废弃
<marquee> CSS 动画 标签废弃
<blink> CSS 动画 标签废弃
5. 表单结构问题

AI 生成的表单常常缺少必要的关联和结构。

AI 原始输出:

<form>
  <div>用户名 <input type="text"></div>
  <div>邮箱 <input type="text"></div>
  <div>性别 <input type="radio"><input type="radio"></div>
  <div><input type="submit" value="提交"></div>
</form>

修正后版本:

<form action="/register" method="POST">
  <div>
    <label for="reg-username">用户名</label>
    <input type="text" id="reg-username" name="username" required>
  </div>

  <div>
    <label for="reg-email">邮箱</label>
    <input type="email" id="reg-email" name="email" required>
  </div>

  <fieldset>
    <legend>性别</legend>
    <label>
      <input type="radio" name="gender" value="male"></label>
    <label>
      <input type="radio" name="gender" value="female"></label>
  </fieldset>

  <button type="submit">提交</button>
</form>

表单审核要点:

  1. 每个 <input> 是否有对应的 <label>(通过 for 关联)
  2. 单选按钮是否共享相同的 name 属性
  3. 是否使用正确的 type(如 emailtelurl
  4. 是否添加 requiredpattern 等验证属性
  5. 是否使用 <fieldset><legend> 分组相关控件
  6. 表单是否有 actionmethod 属性
6. 元数据和文档结构缺失

AI 有时会生成"裸 HTML",缺少必要的文档结构。

AI 原始输出:

<div>
  <h1>我的页面</h1>
  <p>欢迎访问</p>
</div>

修正后版本:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta name="description" content="这是一个示例页面,展示正确的 HTML 文档结构">
  <title>我的页面</title>
</head>
<body>
  <main>
    <h1>我的页面</h1>
    <p>欢迎访问</p>
  </main>
</body>
</html>

二、系统化审核流程

面对 AI 生成的代码,不要直接复制使用。建议按照以下五步法进行系统化审核。

第一步:结构层审核

检查文档骨架是否完整、语义是否正确。

审核清单:

  • 是否包含 <!DOCTYPE html>
  • <html> 是否有 lang 属性
  • <head> 是否包含 charsetviewport
  • 是否使用了恰当的语义化标签(header、nav、main、article、section、aside、footer)
  • 标题层级是否连续(h1 → h2 → h3,无跳级)
第二步:可访问性审核

确保页面对所有用户都友好。

审核清单:

  • 所有 <img> 是否有有意义的 alt 文本
  • 所有表单控件是否有 <label> 关联
  • 颜色对比度是否足够(可借助工具)
  • 交互元素是否可通过键盘访问
  • 错误提示是否有 role="alert"
  • 复杂组件是否有适当的 ARIA 属性
第三步:语法与规范审核

验证 HTML 是否符合标准。

审核清单:

  • 标签是否正确闭合
  • 属性值是否有引号包裹
  • 是否存在嵌套错误(如 p 内嵌 div)
  • 是否使用了过时或废弃的标签/属性
  • ID 是否唯一
  • 类名是否有意义(非 auto-generated 类名)
第四步:性能与 SEO 审核

优化页面加载和搜索引擎表现。

审核清单:

  • 图片是否有 widthheight(防止布局偏移)
  • 是否使用了懒加载 loading="lazy"
  • 外部资源是否有合适的 rel 属性
  • 页面是否有唯一的 <title><meta name="description">
  • 是否使用了语义化标题结构
第五步:验证工具检查

使用自动化工具进行最终验证。

三、使用 W3C Markup Validator

W3C Validator 是检查 HTML 规范性的权威工具,对 AI 生成的代码尤其有用。

在线验证方式
  1. 访问 validator.w3.org
  2. 选择验证方式:
    • Validate by URI:输入网页地址
    • Validate by File Upload:上传 HTML 文件
    • Validate by Direct Input:直接粘贴代码
常见错误及修复
Validator 报错 含义 修复方法
end tag for "p" omitted p 标签未闭合或被截断 检查嵌套,确保 p 内无块级元素
attribute "x" not allowed 使用了不存在的属性 移除或替换为正确属性
element "x" not allowed here 标签嵌套错误 调整嵌套结构
duplicate ID "x" ID 重复 将重复 ID 改为 class 或唯一 ID
The charset attribute on the meta element is obsolete 使用了旧式 meta charset 改为 <meta charset="UTF-8">
命令行验证(高级)

如果你使用 Node.js,可以安装 html-validate 进行本地验证:

# 安装
npm install --save-dev html-validate

# 验证单个文件
npx html-validate page.html

# 验证整个目录
npx html-validate "CODE/**/*.html"

配置文件 .htmlvalidate.json

{
  "extends": ["html-validate:recommended"],
  "rules": {
    "void-style": "omit",
    "no-trailing-whitespace": "error",
    "require-lang": "error"
  }
}

四、实战案例:完整审核演示

以下是一段典型的 AI 生成代码,我们将完整演示审核和修正过程。

AI 原始输出:

<!DOCTYPE html>
<html>
<head>
  <title>产品展示</title>
</head>
<body>
  <div class="header">
    <div class="logo"><img src="logo.png"></div>
    <div class="menu">
      <div class="item"><a href="/">首页</a></div>
      <div class="item"><a href="/products">产品</a></div>
    </div>
  </div>

  <div class="content">
    <div class="product">
      <div class="name">智能手表</div>
      <img src="watch.jpg" width="300">
      <p>价格:<font color="red">¥1999</font></p>
      <button onclick="buy()">立即购买</button>
    </div>
  </div>

  <div class="footer">
    <p>联系我们:contact@example.com</p>
  </div>
</body>
</html>

审核记录:

行号 问题 严重程度 类型
2 缺少 lang 属性 可访问性
4 缺少 charsetviewport 标准规范
7 img 缺少 alt 可访问性
8-11 应使用 <nav><ul> 语义化
15 应使用 <h1><h2> 语义化
16 img 缺少 alt,建议加 height 可访问性/性能
17 <font> 已废弃 过时标签
18 button 缺少 type 规范
21 应使用 <footer> 语义化

修正后版本:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta name="description" content="智能手表产品展示页面">
  <title>产品展示 - 智能手表</title>
</head>
<body>
  <header>
    <div class="logo">
      <img src="logo.png" alt="公司Logo">
    </div>
    <nav>
      <ul>
        <li><a href="/">首页</a></li>
        <li><a href="/products">产品</a></li>
      </ul>
    </nav>
  </header>

  <main>
    <article class="product">
      <h1>智能手表</h1>
      <img src="watch.jpg" alt="黑色智能手表正面展示" width="300" height="300" loading="lazy">
      <p>价格:<span class="price">¥1999</span></p>
      <button type="button" onclick="buy()">立即购买</button>
    </article>
  </main>

  <footer>
    <p>联系我们:<a href="mailto:contact@example.com">contact@example.com</a></p>
  </footer>
</body>
</html>

五、建立你的审查清单

将以下清单保存为书签或打印出来,每次审核 AI 代码时逐项检查。

HTML AI 代码审查清单:

## 文档结构
- [ ] <!DOCTYPE html> 声明存在
- [ ] <html lang="..."> 语言属性设置
- [ ] <meta charset="UTF-8"> 编码声明
- [ ] <meta viewport> 移动端适配
- [ ] <title> 唯一且有意义
- [ ] <meta description> SEO 描述

## 语义化
- [ ] 使用 <header> 而非 <div class="header">
- [ ] 使用 <nav> 包裹主导航
- [ ] 使用 <main> 标识主内容
- [ ] 使用 <article> / <section> 组织内容
- [ ] 使用 <footer> 作为页脚
- [ ] 标题层级 h1-h6 连续无跳级

## 可访问性
- [ ] 所有图片有 alt 属性(装饰性图片用 alt="")
- [ ] 所有表单有 label 关联
- [ ] 表单错误有 role="alert"
- [ ] 按钮有明确的 type 属性
- [ ] 链接文本有意义(无"点击这里")

## 语法规范
- [ ] 无嵌套错误(p 内无 div、a 内无 button)
- [ ] 无过时标签(font、center、marquee)
- [ ] 无过时属性(bgcolor、border、align)
- [ ] ID 唯一不重复
- [ ] 属性值有引号包裹

## 性能优化
- [ ] 图片有 width/height 属性
- [ ] 非首屏图片有 loading="lazy"
- [ ] 无冗余空标签和注释

动手练习

练习 1:找出并修正错误

以下代码由 AI 生成,包含至少 8 处问题。请找出并修正。

<!DOCTYPE html>
<html>
<head>
  <title>练习页面</title>
</head>
<body>
  <div class="header">
    <h1>欢迎来到我的网站</h1>
  </div>
  <div class="main">
    <p>
      这是一段介绍文字。
      <div class="highlight">重点内容</div>
      文字继续。
    </p>
    <img src="photo.jpg" width="600">
    <form>
      <input type="text" placeholder="你的名字">
      <input type="submit">
    </form>
  </div>
</body>
</html>
参考答案
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>练习页面</title>
</head>
<body>
  <header>
    <h1>欢迎来到我的网站</h1>
  </header>
  <main>
    <p>这是一段介绍文字。</p>
    <div class="highlight">重点内容</div>
    <p>文字继续。</p>
    <img src="photo.jpg" alt="风景照片" width="600" height="400">
    <form action="/submit" method="POST">
      <label for="name">你的名字</label>
      <input type="text" id="name" name="name" placeholder="请输入名字">
      <button type="submit">提交</button>
    </form>
  </main>
</body>
</html>

问题清单:

  1. 缺少 lang="zh-CN"
  2. 缺少 charsetviewport
  3. <div class="header"> 应改为 <header>
  4. <div class="main"> 应改为 <main>
  5. <p> 内嵌套 <div> 不合法
  6. <img> 缺少 altheight
  7. 表单输入框缺少 <label>id/name
  8. <input type="submit"> 建议改为 <button type="submit">
  9. 表单缺少 actionmethod

练习 2:语义化改造

将以下纯 div 结构改写为语义化 HTML。

<div class="article-page">
  <div class="top">
    <div class="site-name">技术博客</div>
    <div class="links">
      <span><a href="/">首页</a></span>
      <span><a href="/archive">归档</a></span>
    </div>
  </div>
  <div class="content-area">
    <div class="post">
      <div class="post-title">学习 HTML 语义化</div>
      <div class="post-body">
        <p>语义化是 HTML5 的重要特性...</p>
      </div>
    </div>
    <div class="sidebar">
      <div class="widget">关于作者</div>
    </div>
  </div>
  <div class="bottom">© 2024 技术博客</div>
</div>
参考答案
<body>
  <header>
    <div class="site-name">技术博客</div>
    <nav>
      <ul>
        <li><a href="/">首页</a></li>
        <li><a href="/archive">归档</a></li>
      </ul>
    </nav>
  </header>

  <div class="content-area">
    <main>
      <article>
        <h1>学习 HTML 语义化</h1>
        <div class="post-body">
          <p>语义化是 HTML5 的重要特性...</p>
        </div>
      </article>
    </main>

    <aside class="sidebar">
      <section class="widget">
        <h2>关于作者</h2>
      </section>
    </aside>
  </div>

  <footer>
    <p>© 2024 技术博客</p>
  </footer>
</body>

练习 3:可访问性修复

修正以下表单的可访问性问题。

<form>
  <div>用户名 <input type="text"></div>
  <div>密码 <input type="password"></div>
  <div>
    兴趣:
    <input type="checkbox"> 编程
    <input type="checkbox"> 设计
    <input type="checkbox"> 音乐
  </div>
  <input type="submit" value="注册">
</form>
参考答案
<form action="/register" method="POST">
  <div>
    <label for="username">用户名</label>
    <input type="text" id="username" name="username" required>
  </div>

  <div>
    <label for="password">密码</label>
    <input type="password" id="password" name="password" required>
  </div>

  <fieldset>
    <legend>兴趣</legend>
    <label>
      <input type="checkbox" name="interest" value="programming"> 编程
    </label>
    <label>
      <input type="checkbox" name="interest" value="design"> 设计
    </label>
    <label>
      <input type="checkbox" name="interest" value="music"> 音乐
    </label>
  </fieldset>

  <button type="submit">注册</button>
</form>

常见误区 ⚠️

误区 正确理解
“AI 生成的代码可以直接用” AI 输出是初稿,必须经过审核才能用于生产环境
“Validator 没有报错就是完美代码” 验证器只能检查语法,无法判断语义和可访问性
“只要页面看起来正常就没问题” 视觉正常不代表代码规范,可能存在可访问性隐患
“修正 AI 代码浪费时间,不如自己写” 对于复杂结构,AI 生成+人工审核仍比从零写更高效
“alt 属性随便填就行” alt 应该准确描述图片内容,为空字符串表示装饰性图片
“语义化标签只是锦上添花” 语义化直接影响 SEO、可访问性和代码可维护性
“一次性修正后就不用再管” AI 模型会更新,每次生成都应执行审核流程

速查卡片 📋

AI HTML 代码审核流程

1. 结构审核 → 文档完整性和语义化标签
2. 可访问性审核 → alt、label、ARIA
3. 语法审核 → 嵌套规则、过时标签
4. 性能审核 → 图片优化、元数据
5. 工具验证 → W3C Validator、html-validate

六大高频错误速查

# 错误模式 快速识别 修正要点
1 Div 汤 满屏 <div class="..."> 替换为语义化标签
2 缺失 alt <img> 无 alt 添加描述性 alt
3 嵌套错误 p 内有 div、a 内有 button 调整嵌套结构
4 过时标签 font、center、bgcolor 改用 CSS
5 表单无 label input 无关联 label 添加 for + id
6 文档结构缺失 无 charset、viewport 补全 head 内容

推荐工具

工具 用途 链接
W3C Markup Validator HTML 语法验证 validator.w3.org
html-validate 本地 CLI 验证 npm 包
axe DevTools 可访问性检查 浏览器扩展
Lighthouse 综合性能审计 Chrome 内置
WAVE 可访问性可视化 wave.webaim.org

扩展阅读

下一篇:第36篇:附录——常用AI提示词模板集

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐