XSS跨站脚本攻击深度解析:从实验预习到防御实战

发布时间:2026/10/20 20:58:04

XSS跨站脚本攻击深度解析:从实验预习到防御实战 1. 从一次课堂演示事故说起XSS到底能造成多大破坏很多同学第一次接触XSS是在软件安全实验课上。老师打开一个留言板页面在输入框里敲了一行看似人畜无害的代码回车之后页面弹出了一个对话框。教室里传来一阵笑声大家觉得这不过是个“弹窗小把戏”。但我见过更真实的场景某内部技术分享会上一位讲师演示了一个模拟的在线协作平台他在评论区注入了一段脚本结果所有在线用户的登录态都被悄悄转发到了他的测试服务器上。那一刻全场安静了。这就是XSSCross-Site Scripting跨站脚本攻击的典型特征——看起来简单危害却极其深远。它的本质是攻击者将恶意脚本注入到原本可信的网页中当其他用户浏览该页面时脚本在用户的浏览器环境中执行从而窃取Cookie、篡改页面内容、劫持用户操作、甚至发起蠕虫式传播。这篇预习笔记面向的是正在准备软件安全实验的同学们也适合任何想系统理解XSS原理和防御的开发者。我会从实验预习的角度出发把XSS的分类、原理、利用方式、防御手段以及实验中容易踩的坑全部拆开揉碎讲清楚。你不需要有深厚的安全背景只要会基本的HTML和JavaScript就能跟上。提示本文所有实验环境均为本地搭建的模拟靶场所有案例仅用于教学理解请勿将技术用于任何未经授权的场景。2. XSS的三种面孔反射型、存储型与DOM型在预习阶段最先要搞清楚的就是XSS的分类。很多同学做完实验只知道“输入脚本会弹窗”但说不清楚为什么有的弹窗是一次性的有的却会反复出现。这个区别直接决定了漏洞的危害等级和修复优先级。2.1 反射型XSS一次性的“回音”反射型XSSReflected XSS是最常见也最容易理解的一种。它的工作流程是这样的攻击者构造一个带有恶意脚本参数的URL诱导受害者点击。服务器收到请求后没有对参数做任何处理直接把它“反射”回HTML页面中。浏览器解析这段HTML时脚本就被执行了。举个模拟例子。假设某个搜索页面这样处理查询词p您搜索的关键词是% request.getParameter(keyword) %/p如果攻击者构造这样的URLhttp://localhost:8080/search?keywordscriptalert(xss)/script服务器返回的页面就会变成p您搜索的关键词是scriptalert(xss)/script/p浏览器渲染时script标签被解析执行弹窗出现。反射型XSS的特点是不持久化。恶意脚本存在于URL中不会存储在服务器数据库里。每个受害者都需要点击特制的链接才会触发。因此它通常用于针对特定用户的定向攻击比如通过钓鱼邮件发送链接。注意反射型XSS的触发前提是用户点击了恶意链接。在实验中你可能会觉得“谁会点这种奇怪的链接”但在真实场景中攻击者会通过短链接、二维码、社交工程等手段伪装URL诱导点击的成功率并不低。2.2 存储型XSS埋在地里的“地雷”存储型XSSStored XSS是我个人认为危害最大的一类。恶意脚本被提交到服务器后存储在数据库或文件中。当其他用户访问包含这段数据的页面时脚本自动执行。整个过程不需要受害者点击任何特殊链接只要正常浏览页面就会中招。典型的场景包括留言板、评论区、用户昵称、个人签名、文章标题等。攻击者在这些位置提交带有脚本的内容服务器存储后所有查看该内容的用户都会触发脚本。存储型XSS的可怕之处在于它的传播性。在一个社交平台中如果个人签名存在存储型XSS攻击者可以构造一段自动发送好友请求或自动发布内容的脚本形成蠕虫式传播。2005年曾经出现过一个经典的XSS蠕虫案例在短时间内感染了大量用户就是利用了存储型XSS的自动传播特性。在实验中存储型XSS通常需要你搭建一个带有数据库的模拟留言板或评论系统。提交恶意内容后刷新页面或换一个浏览器访问就能看到脚本自动执行的效果。2.3 DOM型XSS不走服务器的那条路DOM型XSSDOM-based XSS和前两种有一个本质区别恶意脚本的执行完全不经过服务器。它是由于前端JavaScript代码在处理用户输入时不安全地将其插入到DOM中导致的。看一个模拟的代码片段var name location.hash.substring(1); document.getElementById(greeting).innerHTML 你好 name;如果URL是http://localhost:8080/page#img srcx onerroralert(xss)那么location.hash获取到的内容会被直接赋给innerHTML浏览器解析时触发onerror事件脚本执行。DOM型XSS的排查难度相对较高因为它不体现在服务器响应中。你查看页面源代码可能看不到任何异常但浏览器实际渲染的DOM结构已经被篡改了。在实验中这类漏洞通常出现在使用innerHTML、document.write、eval等危险函数的场景。类型是否经过服务器是否持久化典型触发方式危害等级反射型是否点击恶意链接中存储型是是浏览正常页面高DOM型否否点击恶意链接中高3. 浏览器是怎么“帮凶”的XSS的底层执行机制理解XSS不能只停留在“输入脚本会弹窗”这个层面。你需要知道浏览器在什么情况下会把一段文本当作代码执行这涉及到HTML解析、JavaScript执行上下文和同源策略这几个核心概念。3.1 HTML解析器的工作方式浏览器收到HTML文档后会从上到下逐行解析。当解析器遇到script标签时它会暂停HTML解析立即执行其中的JavaScript代码执行完毕后再继续解析。这就是为什么内联脚本能够直接运行。但不仅仅是script标签能执行代码。很多HTML标签的属性也支持JavaScript协议或事件处理。比如img srcx onerroralert(xss) a hrefjavascript:alert(xss)点击/a div onmouseoveralert(xss)悬停试试/div这些标签和属性在特定条件下都会触发脚本执行。攻击者正是利用了浏览器“区分代码和文本”的机制——如果开发者没有正确地对用户输入进行转义浏览器就会把用户输入当作代码来解析。3.2 同源策略与XSS的关系同源策略Same-Origin Policy是浏览器最核心的安全机制之一。它规定来自不同源协议、域名、端口任一不同的页面不能互相读取数据。这个策略本意是防止恶意网站窃取其他网站的数据。但XSS攻击巧妙地绕过了同源策略。因为恶意脚本是在目标网站的页面中执行的对于浏览器来说这段脚本和目标网站是同源的。所以脚本可以自由地读取该网站下的Cookie、LocalStorage、发起同源请求等。这就是为什么XSS能窃取登录态——脚本不是从外部入侵的而是“从内部”获取了信任。提示理解这一点非常重要。很多同学会问“为什么不能直接跨域读Cookie”答案就是同源策略。而XSS的本质是让恶意代码获得了目标源的执行权限从而绕过了这道防线。3.3 Cookie的HttpOnly属性一道关键防线在实验中你可能会尝试用document.cookie来获取用户Cookie。但如果目标网站的Cookie设置了HttpOnly属性JavaScript就无法读取它。这是防御XSS窃取登录态的重要手段。// 如果Cookie设置了HttpOnly这行代码返回空字符串 console.log(document.cookie);在搭建实验靶场时建议你分别测试有HttpOnly和无HttpOnly的情况直观感受这道防线的作用。但要注意HttpOnly只能防止Cookie被读取不能阻止XSS执行其他恶意操作比如篡改页面内容、发起CSRF请求等。4. 实验环境搭建从零构建一个可复现的靶场预习阶段最怕的就是“看懂了但做不出来”。这一节我会给出一个完整的本地实验环境搭建方案基于常见的Web技术栈确保你能在自己的机器上复现所有XSS类型。4.1 技术选型与理由对于软件安全实验我推荐使用Node.js Express 内存存储的方案。原因有三第一Node.js环境搭建简单不需要配置复杂的数据库第二Express框架轻量代码量少便于聚焦安全逻辑本身第三内存存储可以避免数据库安装的麻烦同时支持存储型XSS的演示。如果你更熟悉PythonFlask也是不错的选择。核心思路是一样的一个能够接收用户输入并原样输出到HTML页面的Web应用。4.2 最小化靶场代码下面是一个模拟的留言板应用包含反射型和存储型XSS的漏洞点const express require(express); const app express(); app.use(express.urlencoded({ extended: true })); // 模拟内存存储 let comments []; // 首页展示留言列表存储型XSS漏洞点 app.get(/, (req, res) { let html h1留言板/h1; html form action/comment methodPOST; html input namecontent placeholder输入留言; html button typesubmit提交/button; html /form; html h2所有留言/h2; comments.forEach(c { html div${c}/div; // 未转义存在存储型XSS }); res.send(html); }); // 提交留言 app.post(/comment, (req, res) { comments.push(req.body.content); res.redirect(/); }); // 搜索页面反射型XSS漏洞点 app.get(/search, (req, res) { const keyword req.query.keyword || ; res.send(h1搜索结果/h1p您搜索的是${keyword}/p); // 未转义 }); app.listen(3000, () { console.log(靶场运行在 http://localhost:3000); });这段代码故意没有对用户输入做任何转义处理。你可以用它来测试反射型XSS访问/search?keywordscriptalert(1)/script和存储型XSS提交带有脚本的留言后刷新页面。4.3 实验中的隔离与安全措施在本地做XSS实验时有几点必须注意。第一使用独立的浏览器配置文件或虚拟机。因为XSS实验可能涉及Cookie操作如果你用日常浏览器做实验可能会影响到你真实网站的登录态。第二不要将靶场部署到公网。本地localhost环境足够完成所有实验。第三实验结束后清理浏览器数据避免残留的测试Cookie或缓存影响后续操作。注意有些同学为了图方便直接把靶场代码部署到云服务器上。这是非常危险的行为一旦被扫描到你的服务器可能成为攻击跳板。所有实验务必在本地隔离环境中完成。5. 手工挖掘XSS一套可复用的测试流程知道了原理接下来就是动手找漏洞。这一节我整理了一套在实际测试和实验中都能用的XSS挖掘流程从输入点识别到Payload构造再到绕过过滤逐步推进。5.1 第一步识别所有用户可控的输入点XSS的本质是“用户输入被当作代码执行”所以第一步是找到所有用户能控制的数据入口。常见的输入点包括URL参数?keywordxxx表单字段输入框、文本域、隐藏域HTTP请求头User-Agent、Referer、Cookie文件上传的文件名数据库中的已有数据二次注入在实验中你可以用浏览器的开发者工具F12的Network面板观察每个请求中哪些参数是你可以控制的。把这些参数记录下来逐个测试。5.2 第二步用无害Payload探测输出位置找到输入点后不要一上来就丢scriptalert(1)/script。更稳妥的做法是先输入一个独特的字符串比如xss_test_12345然后查看页面源代码确认这个字符串出现在哪里。如果它出现在HTML标签之间比如divxss_test_12345/div那么你可以尝试注入标签。如果它出现在属性值中比如input valuexss_test_12345那么你需要先闭合属性。如果它出现在script标签内部那么你需要闭合脚本标签或构造合法的JavaScript表达式。这个步骤的目的是确定输出上下文不同的上下文需要不同的Payload构造方式。5.3 第三步根据上下文构造Payload下面是一个按输出上下文分类的Payload速查表输出位置示例测试PayloadHTML标签之间div输入/divscriptalert(1)/scriptHTML属性值内input value输入scriptalert(1)/scriptJavaScript字符串内var a 输入;;alert(1);//JavaScript代码块内script输入/scriptalert(1)URL属性内a href输入javascript:alert(1)在实际实验中你可能会遇到各种过滤规则。比如服务器可能过滤了script标签但可能没有过滤img标签的onerror事件。这时候就需要尝试替代Payloadimg srcx onerroralert(1) svg onloadalert(1) body onloadalert(1) input autofocus onfocusalert(1)5.4 第四步验证与记录当Payload成功执行后不要只满足于弹窗。你需要记录以下信息漏洞的URL、注入点、Payload、输出上下文、浏览器版本。这些信息在撰写实验报告时非常关键。另外尝试思考这个漏洞能造成什么实际影响。比如如果是一个存储型XSS能否窃取其他用户的Cookie能否发起CSRF请求能否篡改页面内容进行钓鱼这种“影响分析”是实验报告中体现深度的重要部分。6. 绕过与对抗当过滤规则出现时怎么办真实的Web应用往往不会让你直接注入script。各种过滤、转义、白名单机制会阻碍你的Payload执行。这一节讨论常见的防御措施以及对应的绕过思路——当然这些知识同样用于理解如何正确防御。6.1 常见过滤规则及其绕过思路大小写过滤有些过滤器只匹配小写的script。可以尝试Script、SCRIPT等变体。但现代浏览器对标签名大小写不敏感所以这种绕过在很多情况下有效。标签黑名单如果script被过滤可以尝试其他标签。比如img srcx onerroralert(1)、svg onloadalert(1)、details open ontogglealert(1)等。浏览器支持的HTML标签有上百个黑名单很难覆盖完全。属性黑名单如果onerror被过滤可以尝试onload、onfocus、onmouseover等。如果所有on开头的事件都被过滤可以尝试javascript:协议在href或src属性中。编码绕过HTML实体编码、URL编码、JavaScript编码都可以用来绕过简单的字符串匹配。比如script可以写成#60;script#62;在某些上下文中浏览器会自动解码。6.2 为什么“过滤”不如“转义”从防御的角度看黑名单过滤是一种非常脆弱的策略。因为HTML和JavaScript的语法极其灵活攻击者总能找到未被过滤的标签或属性组合。正确的做法是输出转义根据输出上下文对用户输入进行相应的编码。HTML上下文将转义为lt;转义为gt;转义为amp;转义为quot;JavaScript上下文将特殊字符转义为Unicode序列URL上下文使用encodeURIComponent进行编码在实验中你可以尝试在靶场代码中加入转义逻辑然后重新测试之前的Payload观察是否还能执行。这种对比实验能让你深刻理解“转义”和“过滤”的区别。6.3 CSP最后一道防线内容安全策略Content Security PolicyCSP是浏览器层面的防御机制。通过设置HTTP响应头网站可以限制哪些来源的脚本可以执行。比如Content-Security-Policy: default-src self; script-src self这表示只允许执行同源的脚本内联脚本和外部脚本都会被阻止。CSP能有效缓解XSS的影响但它不是万能的。如果CSP配置不当比如使用了unsafe-inline防护效果会大打折扣。在实验中你可以尝试给靶场添加CSP头然后观察哪些Payload被阻止了哪些仍然能执行。这能帮助你理解CSP的实际防护边界。7. 防御XSS的工程实践从代码层面堵住漏洞做实验的目的是为了在真实开发中避免这些漏洞。这一节从工程实践的角度总结防御XSS的核心原则和具体做法。7.1 输入验证与输出转义的分工一个常见的误区是“在输入时过滤掉所有特殊字符”。这种做法有两个问题第一它可能破坏正常的业务数据比如用户昵称中确实需要包含符号第二同一条数据可能在不同的上下文中输出输入时的单一过滤无法适配所有场景。正确的做法是输入时做验证确保数据符合预期格式输出时做转义根据上下文进行编码。比如用户年龄字段在输入时验证必须是数字输出到HTML时直接输出即可用户昵称在输入时允许任意字符但在输出到HTML属性或JavaScript变量时分别进行对应的转义。7.2 使用成熟的模板引擎和框架现代Web框架通常内置了自动转义机制。比如ReactJSX中的{}默认对内容进行转义只有使用dangerouslySetInnerHTML时才需要手动处理Vue模板中的{{ }}默认转义v-html需要谨慎使用Django模板变量默认转义|safe过滤器需要谨慎使用Express EJS% %默认转义%- %不转义在实验中你可以对比使用% %和%- %的输出差异直观感受框架的转义机制。但要注意框架的自动转义不是万能的在href、src、onclick等属性中仍然需要额外的处理。7.3 富文本场景的特殊处理很多应用需要允许用户输入富文本比如博客编辑器、评论区的加粗和链接。这种情况下不能简单地全部转义否则富文本格式就丢失了。正确的做法是使用白名单过滤只允许特定的标签和属性其他一律转义或删除。比如可以使用成熟的HTML净化库如DOMPurify它会在客户端对HTML进行白名单过滤移除所有危险的标签和属性。在服务端也可以使用类似原理的库进行二次过滤。提示富文本过滤是一个复杂的话题建议在实验中先理解基本的转义机制再尝试引入白名单过滤库观察过滤前后的差异。8. 实验报告怎么写从“弹窗成功”到“深度分析”很多同学的实验报告只写了“输入Payload后弹窗成功”这样的报告缺乏深度。一份高质量的XSS实验报告应该包含哪些内容我结合自己的经验给出一个框架。8.1 漏洞发现过程的完整记录不要只写最终成功的Payload要把测试过程记录下来。比如首先输入了xss_test发现输出在div标签中然后尝试scriptalert(1)/script发现被过滤接着尝试img srcx onerroralert(1)成功执行。这种“尝试-失败-调整-成功”的过程比单纯的结果更有价值。8.2 漏洞根因的代码级分析找到漏洞后要定位到具体的代码行分析为什么会产生漏洞。比如“在第23行服务器将用户输入的content参数直接拼接到了HTML字符串中没有进行任何转义处理导致浏览器将用户输入解析为HTML标签。”8.3 影响范围与危害评估分析这个漏洞能被谁利用、影响哪些用户、能造成什么后果。比如“该漏洞位于留言板页面属于存储型XSS。任何访问该页面的用户都会执行恶意脚本。攻击者可以窃取用户的Cookie进而劫持登录态。由于留言板对所有登录用户可见该漏洞可能影响全部用户。”8.4 修复方案与验证给出具体的修复代码并验证修复后Payload不再执行。比如“将第23行的${c}改为${escapeHtml(c)}其中escapeHtml函数对、、、进行转义。修复后重新提交scriptalert(1)/script页面显示转义后的文本脚本未执行。”报告章节核心内容常见问题漏洞发现测试步骤与Payload演进只写成功结果缺少过程根因分析定位到具体代码行只描述现象不分析代码影响评估受影响用户与危害泛泛而谈缺少具体场景修复验证修复代码与复测结果只给修复方案不验证9. 预习中容易踩的坑与我的实操心得最后这部分我想分享一些在XSS学习和实验中容易踩的坑以及我个人总结的一些经验。这些内容在教材上通常不会写但能帮你少走很多弯路。9.1 浏览器版本和扩展的影响不同浏览器对XSS的拦截策略不同。Chrome和Edge内置了XSS Auditor虽然现在已弱化可能会拦截某些反射型XSS。Firefox的防护策略又不一样。在实验中如果发现Payload在某个浏览器中不执行先换一个浏览器试试不要急着怀疑自己的Payload有问题。另外浏览器扩展也可能干扰实验结果。比如某些广告拦截插件会阻止包含alert的脚本执行。建议在实验中启用一个干净的浏览器配置文件禁用所有扩展。9.2 编码问题导致的“假成功”有时候你看到页面上显示了scriptalert(1)/script但并没有弹窗。这可能是因为服务器对输入进行了HTML实体编码浏览器把它当作纯文本显示而不是代码执行。这种情况下你看到的“成功”其实是“失败”——漏洞并不存在。判断方法是查看页面源代码CtrlU而不是查看渲染后的页面。如果源代码中显示的是lt;scriptgt;说明输入被转义了如果显示的是script说明漏洞存在。9.3 存储型XSS的“延迟触发”存储型XSS的一个特点是你提交Payload的页面和触发Payload的页面可能不是同一个。比如你在个人资料页面提交了恶意昵称但脚本可能在论坛帖子页面才被执行。在实验中提交Payload后要遍历所有可能显示该数据的位置确认触发点。9.4 不要忽视DOM型XSS很多同学做实验时只关注服务器端返回的HTML忽略了前端JavaScript的动态操作。DOM型XSS的Payload可能完全不经过服务器在URL的hash或search部分就能触发。测试时要特别关注使用了innerHTML、document.write、eval、setTimeout等危险函数的代码。提示在实验中你可以使用浏览器的开发者工具在Sources面板中设置断点跟踪JavaScript的执行流程观察用户输入是如何被处理的。这是理解DOM型XSS的最直观方式。9.5 我的个人体会做了这么多年的安全实验和教学我最大的体会是XSS的防御不是靠某一个措施而是靠多层防线。输出转义是第一道CSP是第二道HttpOnly Cookie是第三道。任何单一措施都可能被绕过但多层叠加后攻击成本会大幅提高。另外不要为了“弹窗成功”而做实验。弹窗只是证明脚本执行了但真正的理解在于为什么这段脚本能执行浏览器在哪个环节把数据当成了代码如果换一个上下文Payload需要怎么调整把这些想清楚了你才算真正掌握了XSS。最后分享一个小技巧在实验中养成记录Payload和对应上下文的习惯。建一个表格左边写输出位置右边写可用的Payload。积累多了之后你会发现自己对XSS的直觉越来越准看到一个输入点就能大致判断出可能的注入方式和绕过思路。这种直觉是任何教材都给不了你的。
延伸阅读

更多相关文章

2026/10/20 20:58:04

智能体持久化记忆架构:三层存储与自主学习闭环实践

1. 从"每轮清零"到"带着记忆工作:这个智能体要解决什么问题去年我在做智能体的时候,反复遇到一个让人哭笑不得的场景:同一个用户,同一类需求,隔了一周再来问,我的智能体完全想不起上次怎么处…

2026/10/20 20:58:04

Intelligent UI本质是前端语义决策系统

1. 这不是“UI设计稿”,而是一套动态决策系统很多人看到“ChatGPT Intelligent UI”这个词,第一反应是:哦,不就是那个带侧边栏、能折叠聊天记录、自动高亮代码块、点击就能复制的界面吗?——这恰恰是最大的认知偏差。我…

2026/10/20 20:53:01

C++中的循环引用

前言 「循环引用」在 C 语境里有两个常见所指:一是智能指针之间的所有权成环,导致引用计数永远降不到零;二是头文件互相包含,导致类型定义顺序或编译依赖出问题。两者都叫循环引用,但机制和解法完全不同。本文以第一类…

2026/10/20 21:49:13

AI女装模特视频生成实战:六款工具对比与完整制作链路

开年以来我一直在帮几个服装类目的店铺做视觉素材,最常被问的问题就是:现在AI生图、AI视频工具这么多,到底该用哪个?尤其最近大家都在聊AI女装模特视频,很多同行一上来就问我哪款工具最牛,我通常会反问一句…

2026/10/20 21:49:13

半监督学习实战指南:从伪标签到一致性正则化的算法与应用

半监督学习在业内一直是个“听着冷门、用着真香”的方向。核心一句话:手头只有少量带标签的数据,却有大量没标签的数据,怎么把模型练好?这几乎是工业界默认的常态——标注贵、标注慢、标注还容易出错,而最不缺的就是裸…

2026/10/20 21:49:13

Flutter工具类库实战复盘:从散装代码到团队基础设施

做Flutter开发这几年,我最怕的不是复杂的嵌套路由,也不是状态管理框架选型,而是那些散落在各个业务文件里的工具方法。早些年我们团队做一款面向多端的应用,每个人都在自己负责的页面里写过日期格式化、手机号脱敏、金额分位处理这…

2026/10/20 21:49:13

LLM服务优化:连续批处理、显存管理与调度策略解析

LLM服务(LLM Serving)大概是过去一年多里被讨论得最多、也最容易被低估的工程课题。训练一个模型可以慢慢磨,把模型跑起来也许只需要一条命令行,但当并发请求从几十涨到几百、承载的业务从聊天扩展到代码补全、RAG问答和生产级Age…

2026/10/20 21:49:13

context-mode:多场景上下文管理的模式化架构设计与实践

1. 从“context-mode”说起:一个被低估的上下文管理思路第一次看到“context-mode”这个词,很多人会下意识地把它归到某个具体框架的配置项里,觉得无非就是个开关或者枚举值。但如果你真正在复杂项目里摸爬滚打过一段时间,就会发现…

2026/10/20 21:43:57

工作区路径信任级别:构建Web管理界面的安全防线

1. 项目概述:当"路径信任"成为Web管理界面的安全命门先别急着看标题里的"工作区路径信任级别"这几个字觉得晦涩——说白了,这就是在回答一个问题:当你在浏览器里打开一个管理界面,操作着服务器上的文件、目录…

2026/10/19 18:06:35

金融AI落地指南:从调研报告到技术选型与工程实践

简介:这份PDF报告聚焦2025年金融服务业中国AI现状与趋势,面向金融科技从业者、AI战略规划人员及关注行业数字化转型的研究者,帮助读者把握生成式AI在银行、支付、交易等场景中的落地路径与投资方向。资源包内含1个PDF文件,大小约1…

2026/10/20 1:05:37

单片机C运行时从启动到多任务:中断安全与共享资源冲突

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

2026/10/20 1:05:37

GCC编译四步详解:预处理、编译、汇编、链接实战

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

2026/10/20 1:05:37

FIW线是什么?FEP注塑线与普通氟塑料线的区别及应用指南

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

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑