Spring Boot四层XSS防御实战:过滤器+包装器+CSP+输出编码

我处理项目里那个"搜索框变成按钮"的Bug,才真正理解XSS不是文档里的一句名词,而是能在几分钟内把Cookie、页面内容、用户操作全部劫走的入口。当时用Spring Boot做的后台管理系统,前端同学随手往标题栏输入了一段带尖括号的内容,页面上直接把标签渲染成了DOM,那一刻所有人都意识到,我们的接口对"代码注入"基本是裸奔。这篇文章就记录我当时从零搭建的"过滤器+请求包装器+输出编码+CSP响应头"四层XSS防御方案,全流程可复现,相关代码都直接贴在章节里,适合正在用Spring Boot开发接口、后台系统或者前后端分离项目的开发者参考。

我记得很清楚,最开始想得很简单:在Controller里对每个参数做replace,把所有尖括号去掉不就行了?结果写完发现自己掉进了一个巨大的坑:接口一多,参数一杂,漏掉一个字段就前功尽弃,而且replace方案对大小写混写、HTML实体编码、属性内联事件根本防不住。后面逐步演化成一套组合方案,核心思路就一句话:不能把安全逻辑散落在业务代码里,要用统一的入口做清洗,再在出口做编码,最后用浏览器安全策略兜底。

1. 理解XSS攻击的实际场景:防御方案的设计起点

1.1 三类XSS攻击与真实业务映射

在做方案之前,我先花了一晚上把项目里可能出现XSS的位置全过了一遍,这时候才发现"哪里会被打"比"怎么防御"更重要。存储型XSS最容易出现在后台系统的评论、公告、商品描述这类入口,攻击者把脚本写进数据库,页面渲染时自动执行;反射型XSS则集中在搜索框、URL参数、跳转参数这类需要回显的地方,攻击者构造一个恶意链接,引诱用户点击,参数里的脚本跟着请求进入后端再原样返回页面;DOM型XSS稍微隐蔽一点,攻击逻辑完全在前端JavaScript里运转,比如从location.hash里取参数拼进DOM,后端甚至看不到完整攻击载荷。

从实际问题来看,如果业务还在用服务端渲染模板(Thymeleaf、JSP),反射型和存储型是重灾区;如果业务已经是前后端分离,后端只提供JSON接口,那么攻击者主要盯的是JSON请求体里的字段,这些数据被前端取走后如果直接插入页面,同样形成存储型XSS。Spring Boot本身没有内置一个"一键防XSS"开关,加上很多团队默认"我们只返回JSON,不会渲染HTML",这个认知错位就是漏洞的温床。防御方案要从这个真实风险出发,而不是从"我觉得别人应该不会这么传"出发。

1.2 两个常被忽略的隐蔽攻击入口

第一个隐蔽入口是HTTP请求头。服务端记录日志、客服系统展示用户设备信息、管理后台展示访客IP归属,都可能把User-Agent、Referer、X-Forwarded-For原样展示在页面上。攻击者只要把脚本放在UA里,管理员一看日志就中招,这种场景在小团队里非常常见,因为大家默认"请求头是浏览器生成的,不会有恶意内容"。

第二个隐蔽入口是文件上传后的内容展示。很多系统上传Excel导入数据,之后把每一行的内容回显到页面上,这些内容是团队自己上传的,潜意识里觉得安全,但Excel单元格里完全能写入<img src=x onerror=alert(1)>,导入后再一展示就触发。我在方案里把这些隐蔽入口也纳入清洗范围,标准很简单:只要数据要从后端流向用户浏览器,就必须经过统一的输出编码或输入清洗,没有任何字段可以豁免。

2. 用过滤器与请求包装器构建统一入口防线

2.1 为什么选Filter而不是拦截器

第一版方案我没考虑拦截器,因为Spring的HandlerInterceptor依赖Spring MVC的HandlerMapping,这意味着静态资源、非Controller路径、部分异常处理路径根本不会进入拦截器。而Servlet的Filter位于整个请求处理链的最前端,Container加载它的时候,请求还没有被映射到任何Controller,这个位置决定了它可以用统一的方式处理所有进来的请求,无论是动态接口、静态资源,还是表单提交。

我用的实现方式是自定义一个XssFilter,在web应用启动时注入到过滤器链的最前面:通过@Order(Ordered.HIGHEST_PRECEDENCE)保证它先于其他过滤器执行。Filter的核心作用不是自己完成所有清洗,而是把原始请求包装成一个"安全请求对象",后续的Controller、Service拿到的都是经过处理后的数据。这样业务代码完全不用关心XSS防御,新增接口也不会因为"忘记过滤"而留漏洞,这是方案能长期维持的根本原因。

2.2 请求包装器的完整实现

过滤器本身很薄,真正干活的是HttpServletRequestWrapper。包装器覆盖了getParameter、getParameterValues、getParameterMap这几个最常见的参数读取入口,做到无论代码里用哪种方式取参数,得到的都是清洗后的值。先看基础版本:

public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper { public XssHttpServletRequestWrapper(HttpServletRequest request) { super(request); } @Override public String getParameter(String name) { return XssCleanUtil.clean(super.getParameter(name)); } @Override public String[] getParameterValues(String name) { String[] values = super.getParameterValues(name); if (values == null) { return null; } String[] cleanValues = new String[values.length]; for (int i = 0; i < values.length; i++) { cleanValues[i] = XssCleanUtil.clean(values[i]); } return cleanValues; } @Override public Map<String, String[]> getParameterMap() { Map<String, String[]> parameterMap = super.getParameterMap(); Map<String, String[]> cleanMap = new HashMap<>(parameterMap.size()); for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) { String[] values = entry.getValue(); String[] cleanValues = new String[values.length]; for (int i = 0; i < values.length; i++) { cleanValues[i] = XssCleanUtil.clean(values[i]); } cleanMap.put(entry.getKey(), cleanValues); } return cleanMap; } }

这里有一个在IndexPage描述不太清楚但实际非常关键的细节:getParameterMap返回的Map通常是不可修改的内部视图,直接修改会报异常,所以必须复制一份新Map。我在第一版踩过这个坑,后来才改成复制的方式。

2.3 JSON请求体清洗的第三种方案

上面包装器解决的是查询参数和表单字段,但现代接口大量使用Content-Type: application/json,RequestBody通过getInputStream()读取,这个时候Filter处理起来就麻烦很多。这个问题的根源在于请求流只能读一次,而Controller的@RequestBody也需要读流,两边会冲突。

在我的实际项目里,我采用的方案是对getInputStream()做缓存包装:包装器第一次初始化时把请求体完整读出来,清洗一遍后存到内存里,之后Controller再读的时候,读的是清洗后的缓存流。这样处理完整保留了原有的JSON结构,又保证了防腐逻辑的统一。示例代码如下:

public class XssBodyRequestWrapper extends HttpServletRequestWrapper { private final String cleanBody; public XssBodyRequestWrapper(HttpServletRequest request) throws IOException { super(request); String rawBody = request.getReader().lines() .collect(Collectors.joining(System.lineSeparator())); this.cleanBody = XssCleanUtil.cleanBody(rawBody); } @Override public BufferedReader getReader() throws IOException { return new BufferedReader(new StringReader(cleanBody)); } @Override public ServletInputStream getInputStream() throws IOException { byte[] bytes = cleanBody.getBytes(StandardCharsets.UTF_8); ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes); return new ServletInputStream() { @Override public boolean isFinished() { return byteArrayInputStream.available() == 0; } @Override public boolean isReady() { return true; } @Override public void setReadListener(ReadListener readListener) { // 保持Servlet InputStream接口完整性 } @Override public int read() { return byteArrayInputStream.read(); } }; } }

这里还有个容易忽略的要点:当请求体经过清洗后,如果包裹的接口调用方用了流式读取,那么必须确保返回的ServletInputStream不是null而且在getInputStream()被调用过之后能正常工作,否则会出现IllegalStateException。我最后上线前把所有接口都回归了一遍,确保getInputStream情况正常。

2.4 清洗引擎的设计与依赖选型

清洗引擎是这套方案最重要的部分。我曾经尝试自己写正则表达式来替换<script>、javascript:、onerror等关键词,实践证明这是一条死胡同:攻击者只需使用<scr<script>ipt>、大小写混写、HTML实体编码、反斜杠变体就能绕过正则。最终我引入了Jsoup的clean方法,它通过白名单机制只保留显式允许的标签和属性,其它全部剔除,这里重点说下常用配置。

<dependency> <groupId>org.jsoup</groupId> <artifactId>jsoup</artifactId> <version>1.16.2</version> </dependency>
public class XssCleanUtil { private static final Whitelist WHITELIST = Whitelist.relaxed() .addProtocols("a", "href", "http", "https") .addProtocols("img", "src", "http", "https"); public static String clean(String value) { if (value == null || value.isEmpty()) { return value; } return Jsoup.clean(value, WHITELIST); } public static String cleanBody(String body) { if (body == null || body.isEmpty()) { return body; } // JSON字符串里嵌套的HTML标签、属性都会被清洗,同时保留JSON结构 return Jsoup.clean(body, WHITELIST); } }

使用Jsoup需要注意的一个实际问题:Whitelist.relaxed()会保留很多标签和属性,如果业务场景是纯文本内容,我更建议直接使用Whitelist.none(),这意味着所有HTML标签都会被剥除,只留下纯文本;如果业务里确实需要富文本编辑器的内容,就需要配合addAttributes、addProtocols做细粒度配置,比如只允许img的src使用http和https协议,禁止javascript:伪协议。项目里的富文本场景我单独走了一条豁免路径,后面在常见问题里细讲。

3. 出口防线与浏览器安全策略:CSP与输出编码

3.1 Content-Security-Policy响应头的配置

入口清洗不是万能的,攻击者还可能通过其它渠道把危险内容投放到页面,所以必须在浏览器端划定安全边界。CSP(内容安全策略)是一种由服务器下发的策略指令,它明确告诉浏览器"哪些来源的脚本可以执行、哪些来源的资源可以加载"。一旦策略生效,即使页面里被注入了<script>标签,浏览器也会拒绝执行。

在Spring Boot里添加CSP响应头最常见的方式是扩展WebSecurityConfigurerAdapter或使用较新的SecurityFilterChain配置,在响应头中加入Content-Security-Policy。一个敞开的初始化版本配置如下:

@Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http.headers(headers -> headers .contentSecurityPolicy(csp -> csp .policyDirectives("default-src 'self'; script-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; frame-ancestors 'none'") ) ); return http.build(); } }

注意script-src 'self'禁止了页面里内联的<script>代码,这是最严格的状态。实际项目里如果前端写了内联脚本或者用了老旧的第三方组件,会把所有脚本执行卡死,这时候可以把这个策略改成script-src 'self' 'unsafe-inline',但这就留下了内联注入的口子。更好的做法是配合随机Nonce值:每次响应生成一个随机的Nonce,只有带这个Nonce的内联脚本才被允许执行。Spring Security支持直接用Nonce配置,我在后续项目中也切换到了这个更高等级的模式。

3.2 Thymeleaf的输出编码与th:text对比

输出编码是最后一个重要环节。在Spring Boot里使用Thymeleaf做页面渲染时,th:text的默认行为就是HTML转义,比如把<script>转成&lt;script&gt;,浏览器拿到只会当普通文本展示。但总有开发为了"方便"直接使用th:utext或[[ ${content} ]],这两个方式输出的是未经转义的HTML,一旦字段内容来自用户输入,就相当于亲手为XSS铺路。

我这里给团队定了一条铁律:凡是展示用户可编辑内容的地方,一律使用th:text,禁止使用th:utext。如果确实需要让富文本编辑器内容正常渲染,就必须配合入口清洗白名单,保证经过Jsoup清洗后只保留安全标签,再使用th:utext渲染,因为这个内容已经是"消毒后"的产物。还有一个容易被忽视的隐藏问题是前后端分离架构下,前端框架的插值语法默认会转义,但v-html和dangerouslySetInnerHTML这类接口是明晃晃的例外,需要前端同学在项目规范里明确禁止或同样配套清洗。

3.3 Cookie安全属性不可忽略

XSS攻击的核心目的之一是窃取登录态Cookie,而HttpOnly属性能从源头阻断脚本读取Cookie。Java后端设置Cookie时加上HttpOnly,浏览器端JavaScript就无法通过document.cookie获得这个值,这等于在XSS陷阱上面加了个保险锁。

Spring Boot里设置HttpOnly Cookie的方式很简单,在Spring Security配置里使用http.csrf()的同时,给Session Cookie加上HttpOnly、Secure属性即可。如果使用自定义的Cookie写入逻辑,需要主动设置cookie.setHttpOnly(true)、cookie.setSecure(true)以及合理的SameSite属性。我在项目里验证过一个场景:攻击者已经通过某个输入点注入了脚本,但尝试读取会话Cookie时得到的只是一个空壳,这个不起眼的属性确实让事故等级直接降了一档。

4. 从测试到落地:验证防御方案是否真的生效

4.1 用MockMvc编写自动化测试

安全方案做完了不能靠直觉判断"应该没问题",必须用测试把每个防御点钉死。我推荐用Spring Boot自带的MockMvc,它对Filter链的模拟非常真实,可以同时验证输入清洗和对响应头的断言。

@SpringBootTest @AutoConfigureMockMvc class XssDefenseTests { @Autowired private MockMvc mockMvc; @Test void shouldCleanScriptTagInQueryParameters() throws Exception { mockMvc.perform(get("/search") .param("keyword", "<script>alert(1)</script>")) .andExpect(status().isOk()) .andExpect(content().string(not(containsString("<script>")))); } @Test void shouldCleanBodyInJsonRequest() throws Exception { String json = "{\"content\":\"<img src=x onerror=alert(1)>\"}"; mockMvc.perform(post("/api/comment") .contentType(MediaType.APPLICATION_JSON) .content(json)) .andExpect(status().isOk()) .andExpect(jsonPath("$.content").value(not(containsString("onerror")))); } @Test void shouldAddContentSecurityPolicyHeader() throws Exception { mockMvc.perform(get("/index")) .andExpect(header().string("Content-Security-Policy", containsString("script-src"))); } }

第一版测试跑通后,我又加了一批"绕过尝试"用例,覆盖大小写混写、HTML实体编码、属性事件、外链脚本这些常见攻击方式。这些用例的价值不仅仅是验证功能,更是给后续维护的人传递一个信息:这些攻击路径是被明确防御过的,改动这部分代码要小心。

4.2 用浏览器开发工具做手动验证

自动化测试之外,强烈建议开发者用浏览器开发工具手动做一轮全链路验证。打开页面的开发者工具,在Console里查看是否有CSP报错,在Network面板查看响应头里是否真的带上了Content-Security-Policy,再切换到Sources面板确认页面源码里<script>标签是否被转义。CSP如果配置生效,即使页面上出现了内联脚本,Console中也会输出"CSP拒绝执行"的明确警告,这种反馈比代码里任何日志都直观。

我常用的一组手动测试载荷:在搜索框输入<script>alert(document.domain)</script>,如果页面弹窗或者出现CSP报错,说明防御存在缺口;输入<img/src=x/onerror=alert(1)>测试属性事件;输入<a href="javascript:alert(1)">test</a>测试伪协议。这组载荷基本能把三种主流绕过路径都覆盖到。

4.3 清理存量脏数据

防御方案上线后,数据库里已经存在的脏数据不会自动变干净。我习惯的做法是:针对用户可编辑的核心字段(昵称、个人简介、评论内容)写一个一次性清理脚本,把历史数据用Jsoup的白名单机制重新清洗一遍,然后再把清洗后的数据更新回库。这个步骤很笨但非常有必要,否则新方案只保护新写入的数据,存量数据一旦被翻出来展示,漏洞依然存在。

另外,线上接口的日志也要检查一遍,确保日志系统没有把包含原始攻击载荷的请求体原样输出到文件。有些监控系统甚至会把带脚本的内容通过邮件报警发出来,技术同事收到电子邮件打开时又中一次招。安全防御必须形成闭环,从请求、存储、输出、日志、监控每一个环节都要覆盖。

5. 实战中的常见坑与排查经验

5.1 过滤器导致JSON请求全部失效

这是这套方案上线那天最惨痛的教训。某跨平台系统采用整体过滤方案时,只加了查询参数的包装器,没有处理请求体缓存流,结果所有POST接口的@RequestBody都拿到空对象,前端全线报错。排查了半个多小时才发现问题:包装器默认的getInputStream()直接透传原始流,Filter和Controller之间有个先后读流顺序,谁先读了,后面的就是空的。

这个问题的标准解法就是我在2.3节写的XssBodyRequestWrapper,把请求体缓存一次,后续的读取全部指向缓存。需要额外注意的一点是,这个缓存方案会占用内存,对于超大文件上传类的接口,建议直接从过滤器中排除,或者设定只处理Content-Type为application/json的请求,避免无谓的性能损耗。

5.2 富文本与XSS防御的冲突

后台系统几乎都有富文本编辑器的需求,这也是最容易和过滤器爆发冲突的地方。团队的编辑器生成的HTML里有style、class、id甚至>

相关新闻

U2-Flash 1M上下文实测:从能塞到能用的工程实践

U2-Flash 1M上下文实测:从能塞到能用的工程实践

1. 当"1M上下文"不再是PPT上的数字第一次看到"1M上下文"这个说法&#xff0c;我的反应是&#xff1a;又一个拿理论值说事的营销话术。做过大模型应用的人都知道&#xff0c;上下文窗口标称值和实际可用值之间&#xff0c;往往隔着一道叫"注意力衰减&q…

2026/10/19 21:02:35 阅读更多 →
Qt通过COM操作Word生成文档:完整实战指南

Qt通过COM操作Word生成文档:完整实战指南

1. 为什么项目里总会冒出"Qt输出Word"的需求做了几年Qt桌面端开发&#xff0c;你会发现一个规律&#xff1a;凡是涉及业务系统、办公自动化的项目&#xff0c;十有八九会碰到"在程序里生成Word文档"这种需求。比如项目里要定期输出月度报告、按模板生成合同…

2026/10/19 21:01:33 阅读更多 →
CNN并行训练模板详解:Keras与TensorFlow多后端对比实践

CNN并行训练模板详解:Keras与TensorFlow多后端对比实践

简介&#xff1a;CNN并行计算代码&#xff08;python版本&#xff09;.zip 是一套面向深度学习初学者的 CNN 并行实现示例&#xff0c;适合希望理解数据并行、模型并行、张量并行及分布式训练概念的 Python 开发者&#xff0c;也适合作为课程实验或性能优化参考。压缩包共 25 个…

2026/10/19 21:00:31 阅读更多 →

最新新闻

【信息科学与工程学】【数据中心】 第十一篇 人工智能智算中心整体设计101 智算中心解决方案 第一部分1.1 智算中心ICT基础设施的定义与边界

【信息科学与工程学】【数据中心】 第十一篇 人工智能智算中心整体设计101 智算中心解决方案 第一部分1.1 智算中心ICT基础设施的定义与边界

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 22:46:04 阅读更多 →
open-code-review:CLI+LLM+Git驱动的开源代码审查新范式

open-code-review:CLI+LLM+Git驱动的开源代码审查新范式

1. 什么是 open-code-review&#xff1a;一个被严重低估的开发者协作新范式open-code-review 不是某个具体软件的名字&#xff0c;也不是某家公司的私有产品&#xff0c;而是一类正在快速成型的技术实践范式——它指代的是基于开源理念、命令行界面&#xff08;CLI&#xff09;…

2026/10/19 22:40:54 阅读更多 →
二轮平衡车全套源码:卡尔曼滤波与PID三环控制实战

二轮平衡车全套源码:卡尔曼滤波与PID三环控制实战

简介&#xff1a;这是一套面向电子爱好者与嵌入式初学者的二轮平衡车DIY完整资料包&#xff0c;涵盖从硬件搭建到软件调试的全链路内容。资源定位为STM32平台平衡车的开源学习套件&#xff0c;包含互补滤波、卡尔曼滤波、DMP三种姿态解算方案的源码&#xff0c;三套工程均编译通…

2026/10/19 22:39:52 阅读更多 →
加扰与解扰:原理、区别及在高速链路中的应用

加扰与解扰:原理、区别及在高速链路中的应用

简介&#xff1a;本资源面向数字通信、FPGA开发与信号处理方向的学习者&#xff0c;围绕加扰与解扰这一核心环节&#xff0c;提供基于VHDL的完整工程实现与验证流程。加扰通过可逆数学变换打散连续相同符号&#xff0c;降低信道自相关与互相关影响&#xff0c;广泛应用于数字电…

2026/10/19 22:35:37 阅读更多 →
数据范围决定算法选型:从O(n log n)到O(n)

数据范围决定算法选型:从O(n log n)到O(n)

我去年处理过一个挺有意思的活儿&#xff1a;某内部工具需要在上亿条日志里按时间窗口做聚合统计&#xff0c;数据的时间戳全部落在最近三个月内。一开始我按教科书思路上了红黑树、跳表这类“高级”结构&#xff0c;结果在真实数据上跑得还不如后来换上的一个普通数组快。原因…

2026/10/19 22:32:32 阅读更多 →
Open Code Review:面向可复现与可审计的代码审查新范式

Open Code Review:面向可复现与可审计的代码审查新范式

1. “open-code-review”不是工具名&#xff0c;而是一类新型代码审查范式的代号你搜“open-code-review”&#xff0c;大概率会撞上一堆零散的 GitHub 仓库、CLI 工具片段、LLM 集成脚本&#xff0c;甚至有人把它当成某个具体开源项目的名称——但其实它根本不是。它是一个正在…

2026/10/19 22:32:32 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介&#xff1a;本资源为电源技术方向的学术研究文档&#xff0c;聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略&#xff0c;面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址&#xff1a; https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集&#xff0c;共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型&#xff08;GMM&#xff09;的语音识别系统&#xff0c;很多人第一反应就是一堆数学公式&#xff0c;觉得门槛很高。但如果你真的在MATLAB里把它落地跑通&#xff0c;会发现核心其实就是三件事&#xff1a;把声音变成特征向量&#xff0c;用GMM给每个类别…

2026/10/19 10:02:04 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人&#xff0c;但落到具体操作上&#xff0c;无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程&#xff1a;对图像做反白、改调色板、彩色转灰度&#xff0c;最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/19 1:30:52 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 2:54:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 9:10:22 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →