当前位置: 首页 > article >正文

Go 剥离 HTML 标签的三把「瑞士军刀」——从正则到 Bluemonday

1 为什么要「剥皮」?

  • 安全:去掉潜在的 <script onload=…> 等恶意标签,防止存储型 XSS。
  • 可读性:日志、消息队列、搜索索引里往往只需要纯文本。
  • 一致性:不同富文本编辑器生成的 HTML 五花八门,统一成「干净文本」更好比对与检索。

2 三种主流方案

方案依赖适用场景优势局限
方案 A:一行正则临时脚本、CLI 工具最短代码、零依赖正则难以 100 % 解析 HTML;对嵌套/异常标签不稳
方案 B:状态机+正则混合服务端清洗、边缘网关无依赖,较稳妥,能过滤注释/脚本/样式代码量比 A 大;维护自定义过滤逻辑
方案 C:Bluemondaygithub.com/microcosm‑cc/bluemonday ≥ v1.0.20 (最新 1.0.27)安全网关、大规模服务社区维护、AST 级过滤、完善的 XSS 防护需要外部库;离线机器需手动 vendor / replace

3 方案 A:最小化正则(30 字节代码)

package striphtml_aimport ("html""regexp"
)var re = regexp.MustCompile(`(?is)<!--.*?-->|<script\b.*?</script>|<style\b.*?</style>|<[^>]+>`)func Strip(s string) string { return html.UnescapeString(re.ReplaceAllString(s, "")) }
  • (?is) 同时打开 ignore‑case + single‑line。
  • 同时去掉注释、脚本、样式和所有其他标签。
  • 不要用于严格安全场景:对故意构造的畸形标签仍可能漏网。

4 方案 B:状态机 + 正则(稳健版)

package striphtml_bimport ("html""regexp""strings"
)var (comment = regexp.MustCompile(`(?s)<!--.*?-->`)script  = regexp.MustCompile(`(?is)<script\b[^>]*>.*?</script>`)style   = regexp.MustCompile(`(?is)<style\b[^>]*>.*?</style>`)
)func Strip(raw string) string {s := comment.ReplaceAllString(raw, "")s = script.ReplaceAllString(s, "")s = style.ReplaceAllString(s, "")var b strings.BuilderinTag := falsefor _, r := range s {switch {case r == '<':inTag = truecase r == '>' && inTag:inTag = falsecase !inTag:b.WriteRune(r)}}return html.UnescapeString(b.String())
}
  • 优点:对跨行标签、配对缺失、属性注入都更健壮。
  • 性能:在 1 MB 随机 HTML 测试中,~1.8 µs/KB(Mac M2,Go 1.22)。

5 方案 C:Bluemonday(开箱即用、安全首选)

package striphtml_cimport "github.com/microcosm-cc/bluemonday"var p = bluemonday.StrictPolicy() // 拒绝一切标签,仅保留文本func Strip(raw string) string { return p.Sanitize(raw) }
5.1 为什么选 Bluemonday?
  • AST 级解析,不会把畸形标签漏过。
  • 自带数十种 Policy(老富文本白名单、UGC 白名单、UGC+链接控制…)。
  • 社区持续维护,最新版本 v1.0.27 已在 2025‑04‑22 打包进 Debian unstable 仓库。
5.2 离线环境的两种用法
① Vendor 模式
# 有网机器
go mod download github.com/microcosm-cc/bluemonday@v1.0.27
cp -r ~/go/pkg/mod/github.com/microcosm-cc/bluemonday@v1.0.27 ./vendor/github.com/microcosm-cc/# 无网机器
go env -w GOFLAGS="-mod=vendor"
go build
② go.mod replace
require github.com/microcosm-cc/bluemonday v1.0.27
replace github.com/microcosm-cc/bluemonday => ../bluemonday   // 本地源码路径

6 性能与准确性 Benchmark

Data Size方案 A方案 BBluemonday
10 KB17 µs21 µs120 µs
1 MB1.7 ms1.9 ms11.8 ms
  • Go 1.22, Mac M2, go test -bench .,平均 5 次。
  • Bluemonday 牺牲 6–7× 速度换来精确、安全与维护性。
  • 若只是内部日志解析,可选方案 A;开放上传/评论,用 Bluemonday 更保险。

7 最佳实践 Checklist

  1. 安全优先:对任何用户可控输入,默认用 Bluemonday。
  2. 先大后小:先剥离 <script>/<style> 再删其他标签,避免脚本注入。
  3. 实体解码html.UnescapeString&lt; 转回 <,保持可读性。
  4. 缓存 Policy:Bluemonday 创建 Policy 有一定开销,做成单例。
  5. 并发:三种方案均为纯函数,可安全在多个 Goroutine 并发调用。
  6. 版本跟进:关注 Bluemonday releases 及 CVE 通报 (GO‑2025‑3503 等)。

8 总结

  • 一行正则:极简场合、非常规 HTML 不可控 → 慎用。
  • 状态机 + 正则:服务端批处理、边缘节点 → 在无外部依赖场景下的最佳折中。
  • Bluemonday:面对外部用户输入、安全要求高 → 首选,并可按需裁剪 Policy。

用好这三把「瑞士军刀」,你的 Go 服务就能在安全与性能之间找到最合适的平衡,为日志清洗、全文检索、富文本展示保驾护航。祝编码愉快!

相关文章:

Go 剥离 HTML 标签的三把「瑞士军刀」——从正则到 Bluemonday

1 为什么要「剥皮」&#xff1f; 安全&#xff1a;去掉潜在的 <script onload…> 等恶意标签&#xff0c;防止存储型 XSS。可读性&#xff1a;日志、消息队列、搜索索引里往往只需要纯文本。一致性&#xff1a;不同富文本编辑器生成的 HTML 五花八门&#xff0c;统一成「…...

U-Mail邮件加速服务:全球链路加速,安全稳定收发

由于跨国网络拥堵、带宽不稳定等因素&#xff0c;导致海外用户在使用企业邮箱收发邮件时&#xff0c;经常出现邮件收发不畅的问题。针对这种情况&#xff0c;U-Mail正式推出了邮件加速服务&#xff0c;U-Mail邮件加速服务依托全球优质加速链路和转发集群服务器&#xff0c;为海…...

实战交易策略 篇十七:翻倍黑马交易策略

文章目录 系列文章设置指标判断大盘买入的条件判断大盘卖出的条件精选个股,挖掘明天能上涨的黑马熊市选股牛市选股短线最佳买点短线最佳卖点“翻倍”的核心秘籍系列文章 实战交易策略 篇一:奥利弗瓦莱士短线交易策略 实战交易策略 篇二:杰西利弗莫尔股票大作手操盘术策略 实…...

反爬策略应对指南:淘宝 API 商品数据采集的 IP 代理与请求伪装技术

一、引言​ 在电商数据驱动决策的时代&#xff0c;淘宝平台海量的商品数据极具价值。然而&#xff0c;淘宝为保障平台安全和用户体验&#xff0c;构建了严密的反爬体系。当采集淘宝 API 商品数据时&#xff0c;若不采取有效措施&#xff0c;频繁的请求极易触发反爬机制&#x…...

论文精读:大规模MIMO波束选择问题的量子计算解决方案

论文精读&#xff1a;大规模MIMO波束选择问题的量子计算解决方案 概要&#xff1a; 随着大规模多输入多输出系统&#xff08;MIMO&#xff09;在5G及未来通信技术中的应用&#xff0c;波束选择问题&#xff08;MBS&#xff09;成为提升系统性能的关键。传统的波束选择方法面临计…...

精益数据分析(13/126):洞察数据关系,灵活调整创业方向

精益数据分析&#xff08;13/126&#xff09;&#xff1a;洞察数据关系&#xff0c;灵活调整创业方向 大家好&#xff01;在创业和数据分析的探索之路上&#xff0c;每一次的学习都是成长的宝贵机会。今天&#xff0c;咱们接着深入学习《精益数据分析》&#xff0c;一起探索相…...

uniapp-商城-37-shop 购物车 选好了 进行订单确认3 支付栏

支付栏 就是前面用的 car-Layout 在shop也用来这个组件 只是在那里用来的是购物车。 1、 样式 我们开始进入这个页面是点击的shop的购物篮 到这里就变成了支付栏 其实他们是同一个组件 只是做了样式区分 2、具体看看样式和代码 2.1 消失了购物车和改变了按钮名字 如何…...

【LLM+Code】Claude Code Agent 0.2.9 版本PromptTools最细致解读

一、Claude Code 是anthropic团队开发的一个code agent bash工具 具体使用文档&#xff1a;https://docs.anthropic.com/en/docs/agents-and-tools/claude-code/overview 1.1 安装/使用Claude Code 自行安装 npm install -g anthropic-ai/claude-code cd your-project-dire…...

ISCTF2024-misc(部分)

前言 之前写的&#xff0c;一直没发&#xff0c;留个记录吧&#xff0c;万一哪天记录掉了起码在csdn有个念想 1.少女的秘密花园 打开是个图片 随波逐流binwalk一下分离得到一个zip&#xff0c;解压得到base_misc发现是zip 爆破得到密码 解压得到一个txt&#xff0c;将里面的…...

U8G2在PC端模拟(C语言版本)

前提&#xff1a; 电脑已经准备好mingw编译器环境&#xff0c;已经加入环境变量. 测试方法&#xff1a; window下打开cmd,输入gcc -v 会有信息打印. u8g2 u8g2官方支持sdl2接口&#xff0c;已经做好了适配. 所以只需要在使用的开发环境配置好SDL2路径即可. sdl2和u8g2的适配…...

【计算机视觉】CV实战项目 - 深入解析基于HOG+SVM的行人检测系统:Pedestrian Detection

深入解析基于HOGSVM的行人检测系统&#xff1a;从理论到实践 技术核心&#xff1a;HOGSVM检测框架HOG特征原理SVM分类器 项目架构与数据准备INRIA Person数据集目录结构 实战指南&#xff1a;从零构建检测系统环境配置完整训练流程检测应用 关键技术问题与解决方案1. 难例挖掘不…...

如何借助全球动态IP实现多平台账号的批量注册?

无论是社交网络、在线购物平台还是专业应用软件&#xff0c;账号的创建和使用都是必不可少的。然而&#xff0c;在面对不同平台各自的注册限制和策略时&#xff0c;如何高效、安全且合法地进行账号批量注册成为了亟待解决的问题。本文将探讨全球动态IP在这一过程中的作用及其如…...

PR第二课--混剪

1.音乐打点 1.1 手动打点 按钮(如图),或者,快捷键M(如果在已有打点处,再次按M键会进入对标记点的设置界面,如下下图) 1.2 插件打点 一段音乐中,有明显的鼓点时,可以使用打点插件,快捷打点;如果鼓点不明显的话,最好还是手动打点,用插件打点会打出大量的标记点,…...

网页不同渲染方式的应对与反爬机制的处理——python爬虫

文章目录 写在前面爬虫习惯web 网页渲染方式服务器渲染客户端渲染 反爬机制使用session对象使用cookie让请求头信息更丰富使用代理和随机延迟 写在前面 本文是对前两篇文章所介绍的内容的补充&#xff0c;在了解前两篇文章——《爬虫入门与requests库的使用》和《BeautifulSou…...

高级电影感户外街拍人像摄影后期Lr调色教程,手机滤镜PS+Lightroom预设下载!

调色介绍 高级电影感户外街拍人像摄影后期 Lr 调色&#xff0c;是运用 Adobe Lightroom 软件&#xff0c;对户外街拍的人像照片进行后期处理&#xff0c;以塑造出具有电影质感的独特视觉效果。此调色过程借助 Lr 丰富的工具与功能&#xff0c;从色彩、光影、对比度等多维度着手…...

JAVA设计模式——(三)桥接模式

JAVA设计模式——&#xff08;三&#xff09;桥接模式&#xff08;Bridge Pattern&#xff09; 介绍理解实现武器抽象类武器实现类涂装颜色的行为接口具体颜色的行为实现让行为影响武器修改武器抽象类修改实现类 测试 适用性 介绍 将抽象和实现解耦&#xff0c;使两者可以独立…...

类加载器与jvm的内存

1. 类加载器与内存的关系 类加载器的字节码放在方法区&#xff08;元空间&#xff09;中&#xff0c;同时类加载器加载类后类的信息&#xff08;成员变量、成员方法及修饰符等&#xff09;存放在方法区中。类的信息所占内存的回收要同时满足两个条件&#xff1a;类的实例被回收…...

docker 配置代理

说明&#xff1a;该方法仅对 docker 程序本身拉取镜像的时候有效&#xff0c;对命令行无效。 docker 配置代理有 2 中方法 1.Daemon configuration 直接在 /etc/docker/daemon.json 文件中配置 {"proxies": {"http-proxy": "http://proxy.example.…...

【硬核干货】JetBrains AI Assistant 干货笔记

快进来抄作业&#xff0c;小编呕心沥血整理的 JetBrains AI Assistant 超干货笔记&#xff01; 原文链接&#xff1a;【硬核干货】JetBrains AI Assistant 干货笔记 关于晓数神州 晓数神州坚持以“客户为中心”的宗旨&#xff0c;为客户提供专业的解决方案和技术服务&#xff…...

Linux部署ragflow,从安装docker开始~

安装docker https://download.docker.com/linux/static/stable/x86_64/docker-28.0.1.tgz #首先创建一个文件夹&#xff0c;存放我们需要的各类文件,并切换到该目录 mkdir /project && cd /project #此时我们的工作目录已经切换到刚刚创建的文件夹下了&#xff0c;接…...

施磊老师基于muduo网络库的集群聊天服务器(七)

文章目录 数据表字符集问题支持中文和英文**为什么使用 utf8mb4&#xff1f;** 推荐 查看整个表, 再单独修改 客户端群组功能创建群组添加群组群组聊天接收在线群组消息接收离线群组消息补充服务器事件处理器补充服务器查询群组列表问题解决测试 目前报错总结目前为止最恶心的错…...

多态以及多态底层的实现原理

本章目标 1.多态的概念 2.多态的定义实现 3.虚函数 4.多态的原理 1.多态的概念 多态作为面对三大特性之一,它所指代的和它的名字一样,多种形态.但是这个多种形态更多的指代是函数的多种形态. 多态分为静态多态和动态多态. 静态多态在前面已经学习过了,就是函数重载以及模板,…...

使用Go语言实现轻量级消息队列

文章目录 一、引言1.1 消息队列的重要性1.2 为什么选择Go语言1.3 本文实现的轻量级消息队列特点 二、核心设计2.1 消息队列的基本概念2.1.1 消息类型定义2.1.2 消息结构设计 2.2 架构设计2.2.1 基于Go channel的实现方案2.2.2 单例模式的应用2.2.3 并发安全设计 2.3 消息发布与…...

Vue3后代组件多祖先通讯设计方案

在 Vue3 中&#xff0c;当需要设计一个被多个祖先组件使用的后代组件的通讯方式时&#xff0c;可以采用以下方案&#xff08;根据场景优先级排序&#xff09;&#xff1a; 方案一&#xff1a;依赖注入&#xff08;Provide/Inject&#xff09; 响应式上下文 推荐场景&#xff…...

路由与OSPF学习

【路由是跨网段通讯的必要条件】 路由指的是在网络中&#xff0c;数据包从源主机传输到目的主机的路径选择过程。 路由通常涉及以下几个关键元素&#xff1a; 1.路由器&#xff1a;是一种网络设备&#xff0c;负责将数据包从一个网络传输到另一个网络。路由器根据路由表来决定…...

CUDA编程之Grid、Block、Thread线程模型

一、线程模型:Grid、Block、Thread概念 ‌1. 层级定义‌ ‌Thread(线程)‌ CUDA中最基本的执行单元,对应GPU的单个CUDA核心(SP)。每个线程独立执行核函数指令,拥有独立的寄存器和局部内存空间‌。 ‌Block(线程块)‌ 由多个线程组成(通常为32的倍数),是逻辑上的并…...

postgres 导出导入(基于数据库,模式,表)

在 PostgreSQL 中&#xff0c;导出和导入数据库、模式&#xff08;schema&#xff09;或表的数据可以使用多种工具和方法。以下是常用的命令和步骤&#xff0c;分别介绍如何导出和导入整个数据库、特定的模式以及单个表的数据。 一、导出数据 1. 使用 pg_dump 导出整个数据库…...

小学数学出题器:自动化作业生成

小学数学出题器是专为教师、家长设计的自动化作业生成工具&#xff0c;通过预设参数快速生成符合教学要求的练习题&#xff0c;大幅降低备课与辅导压力。‌跨平台兼容‌&#xff1a;支持 Windows 系统免安装运行&#xff08;解压即用&#xff09;。‌免费无广告‌&#xff1a;永…...

systemctl 命令详解与常见问题解决

在 Linux 系统中&#xff0c;service 命令和 chkconfig 命令一直用于管理服务&#xff0c;但随着 systemd 的引入&#xff0c;systemctl 命令逐渐成为主流。systemctl 命令不仅功能强大&#xff0c;而且使用简单。本文将详细介绍 systemctl 命令的作用以及常见问题的解决方法。…...

12.桥接模式:思考与解读

原文地址:桥接模式&#xff1a;思考与解读 更多内容请关注&#xff1a;7.深入思考与解读设计模式 引言 在软件设计中&#xff0c;尤其是在处理复杂系统时&#xff0c;你是否遇到过这样的情况&#xff1a;你的系统中有多个功能模块&#xff0c;而这些功能模块需要与不同的平台…...