<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
>
<channel>
<title><![CDATA[Cesii Blog]]></title> 
<atom:link href="https://www.cesii.cn/rss.php" rel="self" type="application/rss+xml" />
<description><![CDATA[Deep testing]]></description>
<link>https://www.cesii.cn/</link>
<language>zh-cn</language>
<generator>emlog</generator>

<item>
    <title>Web安全常见问题-CSP</title>
    <link>https://www.cesii.cn/web-safe/46.html</link>
    <description><![CDATA[<h1>一、先搞懂：CSP到底是干嘛的？</h1>
<p>CSP（Content Security Policy，内容安全策略），是浏览器层面为了防御XSS（跨站脚本攻击）而生的终极安全机制。</p>
<p>你可以把它理解成网站给浏览器装的一道「安全防盗门」：</p>
<ul>
<li>
<p>正常的CSP，会给浏览器列一份「白名单」：只允许加载/执行白名单里的可信资源（比如自己服务器的JS、可信CDN的样式）。</p>
</li>
<li>
<p>不在白名单里的资源、内联脚本、恶意代码，浏览器会直接拦截，从根源上阻断XSS攻击。</p>
</li>
</ul>
<p>而我们遇到的所有问题，本质都是：亲手给这道防盗门开了无数个大洞，让CSP彻底形同虚设。</p>
<h1>二、CSP高危漏洞全拆解</h1>
<h2>1. 漏洞1：CSP中允许内联脚本执行（高危）</h2>
<h3>漏洞名称</h3>
<p>CSP中允许内联脚本执行</p>
<h3>漏洞原因</h3>
<p>在<code>script-src</code>指令中配置了<code>'unsafe-inline'</code>，强制浏览器放行所有内联脚本（包括直接写在HTML里的<code>&lt;script&gt;</code>代码、<code>onclick</code>等内联事件）。</p>
<ul>
<li>
<p>正常CSP默认禁止所有内联脚本，只有手动添加<code>'unsafe-inline'</code>才会放行。</p>
</li>
<li>
<p>这个配置等于告诉浏览器：“不管是我自己写的正常JS，还是黑客注入的恶意内联脚本，全给我放行”，直接废掉了CSP的核心防护。</p>
</li>
</ul>
<h3>风险后果</h3>
<p>黑客只要能在网站任何输入点（评论区、个人资料、URL参数）注入一段恶意内联脚本，就能直接在用户浏览器执行，偷取Cookie、盗号、弹钓鱼广告，XSS攻击零门槛。</p>
<h3>解决方案</h3>
<ul>
<li>
<p>将所有内联脚本、内联事件提取到独立的<code>.js</code>外部文件，彻底删除<code>'unsafe-inline'</code>。</p>
</li>
<li>
<p>必须保留内联脚本的场景：使用<code>nonce</code>（随机数）或<code>hash</code>（脚本哈希）白名单，仅放行可信内联脚本，不全局开放。</p>
</li>
</ul>
<h2>2. 漏洞2：在CSP中的不安全URL方案（高危）</h2>
<h3>漏洞名称</h3>
<p>CSP中使用不安全URL方案（<code>data:</code>/<code>blob:</code>）</p>
<h3>漏洞原因</h3>
<p>在<code>script-src</code>等指令中配置了<code>data:</code>和<code>blob:</code>协议，允许浏览器加载/执行用这两个协议打包的资源。</p>
<ul>
<li>
<p><code>data:</code>/<code>blob:</code>是特殊的打包协议，可以把JS、图片等资源直接编码嵌在URL里，不用单独存成文件。</p>
</li>
<li>
<p>开放<code>data:</code>/<code>blob:</code>给脚本，等于给黑客开了“把恶意代码藏在特殊链接里进门”的大门，CSP完全无法拦截。</p>
</li>
</ul>
<h3>风险后果</h3>
<ul>
<li>黑客可以把恶意JS转成base64，用<code>data:text/javascript;base64,xxx</code>的形式注入，浏览器直接执行，结合<code>'unsafe-inline'</code>形成双重漏洞叠加，XSS攻击成功率拉满。</li>
</ul>
<p>解决方案：</p>
<ul>
<li>
<p>直接从<code>script-src</code>中删除<code>data:</code>和<code>blob:</code>，仅给图片（<code>img-src</code>）等非脚本资源按需放行。</p>
</li>
<li>
<p>必须使用的场景：严格限制仅放行特定类型（如仅图片），绝对不允许脚本类型的<code>data:</code>/<code>blob:</code>。</p>
</li>
</ul>
<h2>3. 漏洞3：在源指令中过度使用宽泛的通配符（高危）</h2>
<h3>漏洞名称</h3>
<p>CSP源指令过度使用<code>*</code>通配符</p>
<h3>漏洞原因</h3>
<p>在<code>script-src</code>、<code>base-uri</code>、<code>form-action</code>等指令中使用了<code>*</code>通配符，代表“允许任意来源的所有资源”。</p>
<ul>
<li>
<p>正常CSP应该只放行可信域名（如<code>'self'</code>、可信CDN域名），<code>*</code>通配符等于完全放弃白名单能力。</p>
</li>
<li>
<p>这个配置等于告诉浏览器：“不管脚本来自哪个网站，是合法的还是黑客的，全给我放行”。</p>
</li>
</ul>
<h3>风险后果</h3>
<p>黑客可以从任何恶意网站、广告链接引入恶意JS，网站毫无阻拦地执行，彻底失去来源管控能力，XSS、数据泄露风险极高。</p>
<h3>解决方案</h3>
<ul>
<li>
<p>彻底删除所有<code>*</code>通配符，替换为具体可信域名，如<code>script-src 'self' https://trusted.cdn.com</code>。</p>
</li>
<li>
<p>核心原则：脚本（<code>script-src</code>）绝对禁止使用<code>*</code>通配符，仅在必要的非脚本资源中谨慎使用。</p>
</li>
</ul>
<h2>4. 漏洞4：绕过对象白名单配置（高危）</h2>
<h3>漏洞名称漏洞名称</h3>
<p>CSP对象源白名单绕过（<code>object-src</code>全放行）</p>
<h3>漏洞原因</h3>
<ul>
<li>
<p><code>object-src</code>指令配置为<code>* data: blob:</code>，无限制放行所有插件/嵌入式对象。</p>
</li>
<li>
<p><code>object-src</code>是CSP中专门管控Flash、<code>&lt;object&gt;/&lt;embed&gt;</code>等插件资源的指令，现代网站几乎不再使用这类插件。</p>
</li>
<li>
<p>全放行配置等于完全不限制插件来源，黑客可以注入恶意Flash/嵌入式对象，直接在用户浏览器执行。</p>
</li>
</ul>
<h3>风险后果</h3>
<p>黑客可以通过恶意插件执行任意代码，绕过CSP的脚本防护，实现提权、数据窃取等攻击，属于额外的攻击入口。</p>
<h3>解决方案</h3>
<ul>
<li>
<p>最优方案：直接配置<code>object-src 'none'</code>，完全禁用所有插件/嵌入式对象，现代网站99%场景适用，对业务零影响。</p>
</li>
<li>
<p>必须使用插件的场景：仅放行可信域名，绝对禁止<code>*</code>、<code>data:</code>、<code>blob:</code>。</p>
</li>
</ul>
<h2>5. 漏洞5：在CSP中使用了不安全的eval()（中危）</h2>
<h3>漏洞名称</h3>
<p>CSP中允许<code>'unsafe-eval'</code></p>
<h3>漏洞原因</h3>
<p>在<code>script-src</code>指令中配置了<code>'unsafe-eval'</code>，允许浏览器执行<code>eval()</code>、<code>new Function()</code>等动态代码。</p>
<ul>
<li>
<p>正常CSP默认禁止<code>eval()</code>执行，手动添加<code>'unsafe-eval'</code>才会放行。</p>
</li>
<li>
<p>这个配置等于给黑客开了“动态代码执行”的绿灯，黑客可以用<code>eval()</code>解密、变形恶意代码，绕过WAF和前端防护。</p>
</li>
</ul>
<h3>风险后果</h3>
<p>放大XSS攻击威力，让黑客可以用更隐蔽的方式注入恶意代码，即使有基础防护也能轻易绕过。</p>
<h3>解决方案</h3>
<ul>
<li>
<p>直接删除<code>'unsafe-eval'</code>，重构代码，用静态代码替代<code>eval()</code>等动态执行逻辑（如用<code>JSON.parse()</code>替代<code>eval()</code>解析JSON）。</p>
</li>
<li>
<p>必须使用的场景：严格限制使用范围，不全局开放<code>'unsafe-eval'</code>。</p>
</li>
</ul>
<h2>6. 低危补充：在CSP中未强制执行脚本中的可信类型</h2>
<h3>漏洞名称</h3>
<p>CSP未开启可信类型（Trusted Types）</p>
<h3>漏洞原因</h3>
<p>未配置<code>require-trusted-types-for 'script'</code>指令，未开启CSP的进阶DOM XSS防护。</p>
<ul>
<li>
<p>可信类型是CSP的扩展防护，强制浏览器只允许执行经过验证的可信脚本，拦截危险的DOM操作（如<code>innerHTML</code>）。</p>
</li>
<li>
<p>未配置该指令，等于没装“第二道锁”，DOM XSS风险依然存在。</p>
</li>
</ul>
<h3>风险后果</h3>
<p>属于锦上添花的防护缺失，优先级低于上述5个高危漏洞，不影响核心安全，但会降低XSS防护能力。</p>
<h3>解决方案</h3>
<ul>
<li>
<p>在CSP中添加<code>require-trusted-types-for 'script'; trusted-types default;</code>，开启可信类型防护。</p>
</li>
<li>
<p>前端无法适配的场景：可标记为低危不整改，不影响等保/密评合规。</p>
</li>
</ul>
<h1>三、所有CSP漏洞的本质总结</h1>
<p>很多人会觉得这是5个独立的问题，但实际上，它们的本质完全一致：</p>
<p>我们配置的CSP，不是在“防护”，而是在主动告诉浏览器：<br />
不管什么JS、谁发来的、哪里来的、用什么方式包装的，全都允许执行。</p>
<p>等于给网站装了防盗门，却亲手把锁拆了、门大开，还贴了纸条：“黑客请随意进”。</p>
<p>这5个配置同时存在，CSP的XSS防护等于彻底报废，没有任何防御能力，黑客可以从任何地方、用任何方法把恶意代码塞进来，浏览器全执行，没有任何阻拦。</p>
<h1>四、最终修复：一份可直接复制的安全CSP模板</h1>
<p>把所有高危配置一次性替换，给你一份零风险的标准CSP配置：</p>
<pre><code>Content-Security-Policy:
  # 默认只允许自家域名的资源
  default-src 'self';
  # 脚本只允许自家服务器，彻底删除unsafe-inline、unsafe-eval、data:、blob:、*
  script-src 'self';
  # 样式允许自家和inline（样式inline通常可保留，脚本inline必须删）
  style-src 'self' 'unsafe-inline';
  # 图片允许自家和data:（仅图片，脚本绝对不加）
  img-src 'self' data:;
  # 字体只允许自家
  font-src 'self';
  # 接口请求只允许自家
  connect-src 'self';
  # 媒体资源只允许自家
  media-src 'self';
  # 直接禁用所有插件，彻底堵死object-src漏洞
  object-src 'none';
  # 禁止篡改页面基础URL
  base-uri 'self';
  # 表单只能提交到自家域名
  form-action 'self';
  # iframe只允许自家
  frame-src 'self';
  # Worker脚本只允许自家
  worker-src 'self';
  # 子资源只允许自家
  child-src 'self';
  # 开启可信类型进阶防护（可选，前端适配后添加）
  # require-trusted-types-for 'script'; trusted-types default;</code></pre>
<h1>核心配置原则</h1>
<ol>
<li>
<p>脚本（<code>script-src</code>）绝对红线：禁止<code>'unsafe-inline'</code>、<code>'unsafe-eval'</code>、<code>data:</code>、<code>blob:</code>、<code>*</code>通配符，只放行可信域名。</p>
</li>
<li>
<p>非脚本资源按需放行：仅给图片、字体等非脚本资源，按需放行<code>data:</code>，绝不给脚本开放。</p>
</li>
<li>
<p>插件彻底禁用：<code>object-src 'none'</code>，现代网站完全用不到，零业务影响，彻底堵死漏洞。</p>
</li>
<li>
<p>通配符零容忍：所有指令彻底删除<code>*</code>，只配置具体可信域名。</p>
</li>
</ol>
<h1>五、修复后验证</h1>
<ol>
<li>
<p>浏览器控制台验证：打开F12控制台，查看是否有CSP相关报错，确保业务功能正常。</p>
</li>
<li>
<p>安全扫描验证：重新执行安全扫描，确认所有CSP相关告警已消除。</p>
</li>
<li>
<p>CSP校验工具验证：使用<a href="https://csp-evaluator.withgoogle.com/">CSP Evaluator</a>等工具，验证CSP策略的安全性。</p>
</li>
<li>
<p>等保/密评合规验证：确认配置符合等保2.0、密评的安全要求，无高危配置。</p>
</li>
</ol>
<h1>六、写在最后</h1>
<p>CSP是防御XSS的最后一道防线，而我们遇到的这些问题，本质都是“主动放弃了这道防线”。</p>
<p>很多时候，开发为了兼容业务、快速解决CSP拦截报错，会随手加上<code>'unsafe-inline'</code>、<code>*</code>、<code>data:</code>这些“万能钥匙”，却忽略了这些配置带来的致命安全风险。</p>
<p>CSP的核心是「<strong>限制</strong>」，不是「放行」。</p>]]></description>
    <pubDate>Sat, 11 Apr 2026 20:24:39 +0800</pubDate>
    <dc:creator>cesii</dc:creator>
    <guid>https://www.cesii.cn/web-safe/46.html</guid>
</item>
<item>
    <title>性能测试计时选型指南：按时间量级选择最优工具</title>
    <link>https://www.cesii.cn/121.html</link>
    <description><![CDATA[<p>作为一个测试工程师，在进行各类性能测试时，总会担心一个问题：</p>
<pre><code>**这个时间这么短，使用这个系统时间戳输出作为结果到底合不合理？这个时间又这么长，通过秒表的方式符合测试的要求么？</code></pre>
<p>往往出现这种情况时总会想：这几种情况有没有一个标准来解答这种情况呢？这种困惑在<code>纳秒级</code>、<code>毫秒级</code>、<code>秒级</code>、<code>分钟</code>、<code>小时</code>、<code>天</code>或者<code>周</code>等不同时间量级的测试中尤为突出，盲目的选择计时方式，轻则导致结果误差过大，重则影响性能瓶颈分析与解决方案的决策。从而梳理了在不同时间量级下的最优计时方案，为以后的测试中提供一个合适的参考。</p>
<h2><strong>一、毫秒级（ms）及以上</strong></h2>
<p><strong> 适用场景</strong></p>
<p>接口响应时间、业务流程总耗时、单机任务执行时长、分布式压测场景下的请求耗时等。</p>
<p>耗时范围<code>1ms~10ms</code>时，是日常性能测试中最常见的场景，这个时候可以选择<code>系统时间戳</code>、<code>专业性能测试工具（JMeter/LoadRunner/Locust）</code>。</p>
<h2><strong>二、秒级（s）及以上</strong></h2>
<p>耗时范围<code>1s-60s</code>时，这个时候除了可以选择<code>系统时间戳</code>、<code>专业性能测试工具（JMeter/LoadRunner/Locust）</code>，还可以选择<code>人工秒表计时</code>或者<code>工业级的计时工具</code>。</p>
<h2><strong>三、纳秒-微秒级（ns-μs）：硬件级高精度，杜绝误差</strong></h2>
<p><strong> 适用场景</strong></p>
<p>函数级指令耗时、硬件IO延迟、芯片级处理时延、短周期算法核心逻辑耗时等，耗时范围＜1ms（μs/ns级），对精度要求极致。</p>
<p>这个时候就要考虑使用<code>CPU TSC（时间戳计数器）</code>、<code>示波器</code>。</p>
<h2><strong>四、几十分钟至数小时长以上</strong></h2>
<p><strong> 适用场景</strong></p>
<p>完整算法执行、大规模数据处理、超算/DCU/FPGA平台全流程测试、系统稳定性压测等，耗时范围≥30min，核心关注总耗时与稳定性。</p>
<p>这个时候就可以考虑使用<code>手机秒表</code>、<code>工业级硬件秒表（支持外部触发、抗干扰强）``人工电子秒表</code></p>
<h2><strong>五、总结</strong></h2>
<p>作为测试工程师，面对不同时间量级的性能测试，<strong>“选对计时工具”是保证结果可信的第一步</strong>。</p>
<ul>
<li>毫秒级及以上任务，系统时间戳、专业压测工具、手机秒表均可灵活选用，精度足够且适配性强；</li>
<li>纳秒级任务必须依赖CPU TSC、示波器等硬件级高精度方案，杜绝普通系统时间戳的误差问题；</li>
<li>几十分钟至数小时的长周期任务，人工/手机/工业秒表是最合理、最可靠的选择。</li>
</ul>]]></description>
    <pubDate>Fri, 23 Jan 2026 22:30:21 +0800</pubDate>
    <dc:creator>cesii</dc:creator>
    <guid>https://www.cesii.cn/121.html</guid>
</item>
<item>
    <title>Jmeter测试时为什么会出现地址被占用（Address already in use）？</title>
    <link>https://www.cesii.cn/jmeter/117.html</link>
    <description><![CDATA[<p>&nbsp;在使用Jmeter进行压力测试时，当tps请求过高时就会出现大量的<strong>Address already in use</strong>错误，空闲时间了解了下原理，原因在于tcp端口不够用导致的。</p>
<p>单台windows最大tcp端口是65535个（默认1024个），客户端每发一次请求就会占据一个端口，如果超出这个数量或者说tcp端口释放比较的慢，就会出现被占用的错误。</p>
<p>JMeter默认是使用短链接方式（关闭 Keep-Alive）进行请求的，windows中端口默认释放时间是120s，即使这个请求结束后，如果还没到达端口释放的时间，这个端口会一直被占用状态。</p>
<p><img src="https://cesii.cn/content/uploadfile/202511/03a41763294971.png" alt="" /></p>
<h3>如何避免？</h3>
<h4>1、多机负载</h4>
<p>使用两台或更多的机器进行负载测试；</p>
<h4>2、虚拟机</h4>
<p>原理和多机负责其实是一个，只不过如果只有一台电脑，那这个时候我们就可以考虑开虚拟机的方式进行，当然要保证你的机器配置足够，否则即使用负载的方式进行也会因为资源不够导致结果不准确或者报错超时。</p>
<h4>3、开启Keep-Alive</h4>
<p><img src="https://cesii.cn/content/uploadfile/202511/453a1763295877.png" alt="" /><br />
打开Jmeter中的Keep-Alive后，可以让请求保持长链接的状态，而不是请求完就断开。</p>
<h4>4、修改Time_wait、最大连接数</h4>
<p>windows默认连接数1024个，这里将windows默认的tcp释放时间缩短，将tcp默认链接数量设置最大，在windows的<code>regedit</code>注册表中修改即可</p>
<p>cmd输入<code>regedit</code>进入到负载机的注册表，找到<code>HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters</code>路径：<br />
<img src="https://cesii.cn/content/uploadfile/202511/68a01763296003.png" alt="" /><br />
在<code>Parmeters</code>右键新建DWORD值，命名为<code>MaxUserPort</code>，然后选择十进制并输入数据65534后保存<br />
<img src="https://cesii.cn/content/uploadfile/202511/646c1763296084.png" alt="" /></p>
<p>在同样的注册表位置新建<code>TcpTimeWaitDelay</code>，值类型DWORD，数值数据为5s(时间可以更短)<br />
<img src="https://cesii.cn/content/uploadfile/202511/66611763296312.png" alt="" /></p>
<p>确定后重启测试机即可。</p>]]></description>
    <pubDate>Sun, 16 Nov 2025 20:04:29 +0800</pubDate>
    <dc:creator>cesii</dc:creator>
    <guid>https://www.cesii.cn/jmeter/117.html</guid>
</item>
<item>
    <title>Linux 基础权限学习（rwx-）</title>
    <link>https://www.cesii.cn/linux/116.html</link>
    <description><![CDATA[<p>接触Linux的一点皮毛，没有仔细了解过Linux权限的代表的含义，或者说了解的没有那么全，最常见的也是7xx，直到今天算是仔细的了解下。</p>
<p>在linux中，权限用户分为三组，分别是<code>所有者用户</code>，<code>所属组用户</code>、<code>其他用户</code>；<br />
权限功能分为读（read）简写<code>r</code>，写（write）简写<code>w</code>，可执行（execute）简写<code>x</code>；还有<code>-</code>，表示无任何权限<br />
这三种用户权限是有各自的权重的，分别为 <code>4</code> <code>2</code> <code>1</code> <code>0</code></p>
<h3>一、基础权限：3 位数字（用户 / 组 / 其他）</h3>
<p><img src="https://cesii.cn/content/uploadfile/202510/3ac61761139629.png" alt="" /></p>
<p><strong>例如：</strong><br />
以 755（<code>rwx r-x r-x</code>） 为例，三位数字分别对应：<br />
第一位 7：文件所有者的权限（r+w+x，4+2+1=7）<br />
第二位 5：所属组用户的权限（r+x，4+1=5）<br />
第三位 5：其他用户的权限（r+x，4+1=5）</p>
<p>755全部组合起来一起的权限就是：所有者用户<code>可读可写可执行</code>，所属组用户<code>可读可执行，但不能写</code>；其他用户<code>可读可执行不能写</code>；</p>
<h3>二、基础权限组合：0-7 的数字含义</h3>
<p>每类对象（u/g/o）的权限是上述 3 个基础权限的数字和，范围为 0-7，具体组合如下：<br />
<img src="https://cesii.cn/content/uploadfile/202510/94261761139905.png" alt="" /></p>
<h3>三、完整权限表示：3 位数字组合（<code>u</code>-<code>g</code>-<code>o</code>）</h3>
<p><img src="https://cesii.cn/content/uploadfile/202510/13981761139979.png" alt="" /></p>
<h3>总结</h3>
<p>基础权限：3 位数字，对应<code>u</code>-<code>g</code>-<code>o</code>的<code>r(4)</code>、<code>w(2)</code>、<code>x(1)</code>组合，范围<code>000-777</code>。<br />
权限对文件和目录的含义不同，核心区别在于<code>x</code>（文件是执行，目录是进入）和<code>w</code>（文件是修改内容，目录是增删文件）。<br />
通过<code>chmod</code>命令可设置权限（如<code>chmod 755 file</code>），<code>ls -l</code>可查看权限字符（如<code>-rwxr-xr-x</code>）。</p>]]></description>
    <pubDate>Wed, 22 Oct 2025 21:05:24 +0800</pubDate>
    <dc:creator>cesii</dc:creator>
    <guid>https://www.cesii.cn/linux/116.html</guid>
</item>
<item>
    <title>Jmeter快速上手流程</title>
    <link>https://www.cesii.cn/jmeter/115.html</link>
    <description><![CDATA[<p>第一次上手Jmeter难免会遇到一些问题，不知道该如何下手...，相比LoadRunner来说，Jmeter会相对更易上手。<br />
一个完整的Jmeter测试流程包括<strong>线程组</strong>、<strong>HTTP请求</strong>、<strong>头管理</strong>、<strong>结果树</strong>、<strong>综合分析报告</strong>。</p>
<h4>流程图：</h4>
<p><img src="https://cesii.cn/content/uploadfile/202509/42711758312331.png" alt="" /></p>
<h4>结构图：</h4>
<p><img src="https://cesii.cn/content/uploadfile/202509/da711758312402.png" alt="" /><br />
示例：从百度查询‘测试信息’。<br />
<img src="https://cesii.cn/content/uploadfile/202509/84591758312560.png" alt="" /><br />
<img src="https://cesii.cn/content/uploadfile/202509/43131758312705.png" alt="" /><br />
<img src="https://cesii.cn/content/uploadfile/202509/7a801758312991.png" alt="" /><br />
开始执行1次后，能否看到结果树中返回了对应的响应信息，包括响应正常、响应异常的部分（绿色正常、红色异常）<br />
<img src="https://cesii.cn/content/uploadfile/202509/3fa51758313691.png" alt="" /><br />
如果想对此api进行一定时间的测试，只需要修改持续时间即可，如设置持续时间为300秒；300后自动停止<br />
<img src="https://cesii.cn/content/uploadfile/202509/9c751758313167.png" alt="" /><br />
聚合报告中能看到请求了多少次、响应时间等信息<br />
<img src="https://cesii.cn/content/uploadfile/202509/e26b1758313333.png" alt="" /><br />
<img src="https://cesii.cn/content/uploadfile/202509/b2f41758313666.png" alt="" /></p>]]></description>
    <pubDate>Sat, 20 Sep 2025 03:58:56 +0800</pubDate>
    <dc:creator>cesii</dc:creator>
    <guid>https://www.cesii.cn/jmeter/115.html</guid>
</item>
<item>
    <title>JS特效-新年（灯笼）</title>
    <link>https://www.cesii.cn/js/10.html</link>
    <description><![CDATA[<pre><code class="language-javascript">(function () {
    // 动态添加样式
    const style = document.createElement('style');
    style.type = 'text/css';
    style.innerHTML = `
        /* 基础样式重置 */
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        /* 防止页面滚动 */
        body {
            overflow: hidden;
            width: 100vw;
            height: 100vh;
        }

        /* 灯笼容器样式 */
        .deng-box {
            position: fixed;
            top: -30px;
            left: 10px;
            z-index: 9999;
            pointer-events: none;
            animation: float 5s ease-in-out infinite;
            filter: drop-shadow(0 0 15px rgba(255, 215, 0, 0.6));
        }

        .deng-box1 {
            position: fixed;
            top: -30px;
            right: 10px;
            z-index: 9999;
            pointer-events: none;
            animation: float 7s ease-in-out infinite 1s;
            filter: drop-shadow(0 0 15px rgba(255, 215, 0, 0.6));
        }

        /* 灯笼主体 - 经典中国红 */
        .deng-box1 .deng,
        .deng {
            position: relative;
            width: 140px;
            height: 110px;
            margin: 50px;
            background: #d8000f;
            border-radius: 50% 50%;
            transform-origin: 50% -120px;
            animation: swing 3s infinite ease-in-out;
            box-shadow: -5px 5px 60px 8px rgba(250, 108, 0, 0.6),
                        0 0 20px rgba(255, 255, 0, 0.4) inset;
            transition: all 0.3s;
            cursor: pointer;
        }

        .deng:hover {
            transform: scale(1.08);
            box-shadow: -5px 5px 70px 10px rgba(250, 108, 0, 0.7),
                        0 0 30px rgba(255, 255, 0, 0.5) inset;
            filter: brightness(1.1);
        }

        .deng-box1 .deng {
            animation: swing 5s infinite ease-in-out;
        }

        /* 灯笼内部装饰 */
        .deng-a {
            position: relative;
            width: 120px;
            height: 110px;
            background: rgba(216, 0, 15, 0.1);
            margin: 15px 8px 8px 8px;
            border-radius: 50% 50%;
            border: 2px solid #dc8f03;
            box-shadow: 0 0 12px rgba(255, 215, 0, 0.5) inset;
            overflow: hidden;
        }

        .deng-a:before {
            content: "";
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: radial-gradient(circle at center, transparent 30%, rgba(255, 215, 0, 0.3) 100%);
            border-radius: 50%;
        }

        .deng-b {
            position: relative;
            width: 55px;
            height: 110px;
            background: rgba(216, 0, 15, 0.1);
            margin: -4px 8px 8px 32px;
            border-radius: 50% 50%;
            border: 2px solid #dc8f03;
            box-shadow: 0 0 12px rgba(255, 215, 0, 0.5) inset;
            overflow: hidden;
        }

        .deng-b:before {
            content: "";
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: radial-gradient(circle at center, transparent 30%, rgba(255, 215, 0, 0.3) 100%);
            border-radius: 50%;
        }

        /* 灯笼挂绳 */
        .xian {
            position: absolute;
            top: -25px;
            left: 70px;
            width: 2px;
            height: 25px;
            background: linear-gradient(to bottom, #dc8f03, #f5d742);
            box-shadow: 0 0 4px rgba(255, 215, 0, 0.6);
        }

        /* 灯笼穗子 - 金色渐变 */
        .shui-a {
            position: relative;
            width: 5px;
            height: 25px;
            margin: -5px 0 0 67px;
            animation: swing 4s infinite ease-in-out;
            transform-origin: 50% -50px;
            background: linear-gradient(to bottom, #dc8f03, #ffcc00);
            border-radius: 0 0 5px 5px;
        }

        .shui-b {
            position: absolute;
            top: 16px;
            left: -2px;
            width: 10px;
            height: 10px;
            background: #dc8f03;
            border-radius: 50%;
            box-shadow: 0 0 6px #ffcc00;
        }

        .shui-c {
            position: absolute;
            top: 20px;
            left: -2px;
            width: 10px;
            height: 45px;
            background: linear-gradient(to bottom, #dc8f03, #ffcc00);
            border-radius: 0 0 0 5px;
        }

        /* 灯笼顶部和底部装饰 */
        .deng:before {
            position: absolute;
            top: -7px;
            left: 34px;
            height: 12px;
            width: 70px;
            content: " ";
            display: block;
            z-index: 999;
            border-radius: 5px 5px 0 0;
            border: solid 2px #dc8f03;
            background: linear-gradient(to right, #dc8f03, #ffa500, #dc8f03);
            box-shadow: 0 0 10px rgba(255, 215, 0, 0.7);
        }

        .deng:after {
            position: absolute;
            bottom: -7px;
            left: 10px;
            height: 12px;
            width: 70px;
            content: " ";
            display: block;
            margin-left: 25px;
            border-radius: 0 0 5px 5px;
            border: solid 2px #dc8f03;
            background: linear-gradient(to right, #dc8f03, #ffa500, #dc8f03);
            box-shadow: 0 0 10px rgba(255, 215, 0, 0.7);
        }

        /* 灯笼文字 - 经典红色 */
        .deng-t {
            font-family: "华文行楷", "楷体", Arial, sans-serif;
            font-size: 3.8rem;
            color: #ffd700;
            text-shadow: 0 0 12px #D8000F;
            font-weight: bold;
            line-height: 105px;
            text-align: center;
            user-select: none;
        }

        /* 灯笼光晕效果 - 金色 */
        .light-effect {
            position: fixed;
            width: 200px;
            height: 200px;
            border-radius: 50%;
            background: radial-gradient(circle at center, rgba(255, 215, 0, 0.5) 0%, transparent 70%);
            filter: blur(25px);
            z-index: -1;
            pointer-events: none;
            opacity: 0;
            animation: lightPulse 3s infinite ease-in-out;
        }

        /* 高亮节日文字元素 - 红色 */
        .festival-text {
            position: fixed;
            font-family: "华文行楷", "楷体", sans-serif;
            font-size: 4rem;
            color: #d8000f;
            text-shadow: 0 0 10px #ffd700;
            animation: floatText 30s infinite ease-in-out;
            opacity: 0;
            z-index: -1;
            pointer-events: none;
            font-weight: bold;
            transition: opacity 2s ease-in-out;
        }

        /* 节日祝福语 */
        .greeting {
            position: fixed;
            bottom: 30px;
            left: 0;
            width: 100%;
            text-align: center;
            font-family: "华文行楷", "楷体", sans-serif;
            font-size: 3rem;
            color: #d8000f;
            text-shadow: 0 0 15px #ffd700;
            z-index: 9999;
            pointer-events: none;
            animation: textGlow 3s infinite alternate;
        }

        /* 灯笼点击效果 - 金色 */
        .click-effect {
            position: fixed;
            width: 50px;
            height: 50px;
            border-radius: 50%;
            background: radial-gradient(circle, rgba(255, 215, 0, 0.7) 0%, rgba(255, 215, 0, 0) 70%);
            animation: clickEffect 1s ease-out forwards;
            pointer-events: none;
            z-index: 9999;
        }

        /* 灯笼粒子效果 - 金色 */
        .lantern-particle {
            position: fixed;
            width: 5px;
            height: 5px;
            border-radius: 50%;
            background: rgba(255, 215, 0, 0.7);
            box-shadow: 0 0 8px #ffd700;
            animation: particleFloat 4s linear infinite;
            pointer-events: none;
            z-index: -1;
        }

        /* 鞭炮效果 */
        .firecracker {
            position: fixed;
            width: 6px;
            height: 18px;
            background: linear-gradient(to bottom, #ff0000, #ff6600);
            border-radius: 2px;
            z-index: 9999;
            animation: firecrackerFall 1s ease-in forwards;
        }

        .explosion {
            position: fixed;
            width: 8px;
            height: 8px;
            border-radius: 50%;
            background: radial-gradient(circle, #ff6600, #ff0000);
            box-shadow: 0 0 15px #ff6600;
            z-index: 9999;
            animation: explosion 0.5s ease-out forwards;
        }

        .explosion-particle {
            position: fixed;
            width: 3px;
            height: 3px;
            border-radius: 50%;
            background: #ffcc00;
            box-shadow: 0 0 6px #ffcc00;
            z-index: 9999;
            animation: explosionParticle 1s ease-out forwards;
        }

        .paper-fragment {
            position: fixed;
            width: 3px;
            height: 5px;
            background: linear-gradient(to bottom, rgba(255, 0, 0, 0.8), rgba(255, 204, 0, 0.6));
            border-radius: 2px 5px;
            z-index: 9999;
            animation: fragmentFall 1.5s ease-in forwards;
            transform-origin: center;
            box-shadow: 0 0 4px rgba(255, 0, 0, 0.5);
        }

        /* 动画效果 */
        @keyframes swing {
            0% {
                transform: rotate(-10deg);
            }
            50% {
                transform: rotate(10deg);
            }
            100% {
                transform: rotate(-10deg);
            }
        }

        @keyframes float {
            0%, 100% {
                transform: translateY(0);
            }
            50% {
                transform: translateY(-20px);
            }
        }

        @keyframes clickEffect {
            0% {
                transform: scale(0.5);
                opacity: 1;
            }
            100% {
                transform: scale(3);
                opacity: 0;
            }
        }

        @keyframes floatText {
            0%, 100% {
                transform: translate(var(--startX), var(--startY)) rotate(var(--rotate)) scale(1);
                opacity: 0;
            }
            20%, 80% {
                opacity: 0.8;
            }
            50% {
                transform: translate(var(--midX), var(--midY)) rotate(var(--rotate)) scale(1.1);
            }
        }

        @keyframes particleFloat {
            0% {
                transform: translate(0, 0) scale(1);
                opacity: 0;
            }
            10% {
                opacity: 1;
            }
            90% {
                opacity: 1;
            }
            100% {
                transform: translate(var(--px), var(--py)) scale(0);
                opacity: 0;
            }
        }

        @keyframes firecrackerFall {
            0% {
                transform: translateY(-150px) rotate(0deg);
                opacity: 1;
            }
            100% {
                transform: translateY(0) rotate(360deg);
                opacity: 1;
            }
        }

        @keyframes explosion {
            0% {
                transform: scale(0.5);
                opacity: 1;
            }
            100% {
                transform: scale(12);
                opacity: 0;
            }
        }

        @keyframes explosionParticle {
            0% {
                transform: translate(0, 0) scale(1);
                opacity: 1;
            }
            100% {
                transform: translate(var(--px), var(--py)) scale(0);
                opacity: 0;
            }
        }

        @keyframes fragmentFall {
            0% {
                transform: translate(0, 0) rotate(0deg) scale(1);
                opacity: 1;
            }
            100% {
                transform: translate(var(--px), var(--py)) rotate(var(--rotate)) scale(0.3);
                opacity: 0;
            }
        }

        @keyframes lightPulse {
            0%, 100% {
                opacity: 0.3;
                transform: scale(0.9);
            }
            50% {
                opacity: 0.6;
                transform: scale(1.1);
            }
        }

        @keyframes textGlow {
            0% {
                text-shadow: 0 0 10px #ffd700;
            }
            100% {
                text-shadow: 0 0 25px #ffd700;
            }
        }

        /* 响应式调整 */
        @media (max-width: 768px) {
            .deng-box, .deng-box1 {
                transform: scale(0.7);
            }

            .greeting {
                font-size: 2.2rem;
            }

            .festival-text {
                font-size: 3rem;
            }

            .deng {
                width: 120px;
                height: 90px;
            }

            .deng-t {
                font-size: 3.2rem;
                line-height: 85px;
            }
        }
    `;
    document.head.appendChild(style);

    // 经典节日文字
    const texts = ['福', '禄', '寿', '喜', '财', '吉', '祥', '春', '节', '乐'];

    // 添加高亮节日文字元素
    function createFestivalTexts() {
        for (let i = 0; i &lt; 15; i++) {
            const text = document.createElement('div');
            text.className = 'festival-text';
            text.textContent = texts[Math.floor(Math.random() * texts.length)];

            // 随机起始位置
            const startX = Math.random() * window.innerWidth;
            const startY = Math.random() * window.innerHeight;
            text.style.left = `${startX}px`;
            text.style.top = `${startY}px`;

            // 随机运动路径
            const midX = startX + (Math.random() - 0.5) * 300;
            const midY = startY + (Math.random() - 0.5) * 300;

            text.style.setProperty('--startX', '0px');
            text.style.setProperty('--startY', '0px');
            text.style.setProperty('--midX', `${midX - startX}px`);
            text.style.setProperty('--midY', `${midY - startY}px`);
            text.style.setProperty('--rotate', `${Math.random() * 30 - 15}deg`);

            // 随机动画时间
            const duration = Math.random() * 20 + 25;
            text.style.animationDuration = `${duration}s`;

            // 随机延迟
            text.style.animationDelay = `${Math.random() * 8}s`;

            // 随机大小
            const size = Math.random() * 2 + 3;
            text.style.fontSize = `${size}rem`;

            document.body.appendChild(text);

            // 随机显示/隐藏
            animateTextFade(text);
        }
    }

    // 文字淡入淡出动画
    function animateTextFade(text) {
        let isVisible = false;
        const minDelay = 3000;
        const maxDelay = 8000;

        function toggleVisibility() {
            isVisible = !isVisible;
            text.style.opacity = isVisible ? '0.8' : '0';

            const nextDelay = Math.random() * (maxDelay - minDelay) + minDelay;
            setTimeout(toggleVisibility, nextDelay);
        }

        // 初始延迟
        const initialDelay = Math.random() * 5000;
        setTimeout(toggleVisibility, initialDelay);
    }

    // 创建鞭炮爆炸效果
    function createFirecrackerExplosion(x, y) {
        // 创建鞭炮下落效果 - 从当前位置上方150px处落下
        const firecracker = document.createElement('div');
        firecracker.className = 'firecracker';
        firecracker.style.left = `${x}px`;
        firecracker.style.top = `${y - 150}px`;
        document.body.appendChild(firecracker);

        // 鞭炮落地后爆炸
        setTimeout(() =&gt; {
            firecracker.remove();

            // 创建爆炸中心
            const explosion = document.createElement('div');
            explosion.className = 'explosion';
            explosion.style.left = `${x - 4}px`;
            explosion.style.top = `${y - 4}px`;
            document.body.appendChild(explosion);

            // 创建爆炸粒子
            for (let i = 0; i &lt; 20; i++) {
                const particle = document.createElement('div');
                particle.className = 'explosion-particle';
                particle.style.left = `${x}px`;
                particle.style.top = `${y}px`;

                // 随机运动方向
                const px = (Math.random() - 0.5) * 100;
                const py = (Math.random() - 0.5) * 100;
                particle.style.setProperty('--px', `${px}px`);
                particle.style.setProperty('--py', `${py}px`);

                document.body.appendChild(particle);

                // 移除粒子
                setTimeout(() =&gt; {
                    particle.remove();
                }, 1000);
            }

            // 创建爆炸碎片
            for (let i = 0; i &lt; 20; i++) {
                const fragment = document.createElement('div');
                fragment.className = 'paper-fragment';
                fragment.style.left = `${x}px`;
                fragment.style.top = `${y}px`;

                // 随机运动方向
                const px = (Math.random() - 0.5) * 100;
                const py = Math.random() * 100 + 50;
                fragment.style.setProperty('--px', `${px}px`);
                fragment.style.setProperty('--py', `${py}px`);
                fragment.style.setProperty('--rotate', `${Math.random() * 360}deg`);

                document.body.appendChild(fragment);

                // 移除碎片
                setTimeout(() =&gt; {
                    fragment.remove();
                }, 1500);
            }

            // 移除爆炸中心
            setTimeout(() =&gt; {
                explosion.remove();
            }, 500);

        }, 1000);
    }

    // 随机生成鞭炮爆炸 - 修改后的版本
    function randomFirecracker() {
        // 在整个页面范围内随机位置
        const x = Math.random() * window.innerWidth;
        const y = Math.random() * window.innerHeight;

        // 确保鞭炮不会太靠近边缘
        const margin = 50;
        const adjustedX = Math.max(margin, Math.min(x, window.innerWidth - margin));
        const adjustedY = Math.max(margin, Math.min(y, window.innerHeight - margin));

        createFirecrackerExplosion(adjustedX, adjustedY);

        // 随机下次爆炸时间
        const nextDelay = Math.random() * 3000 + 2000;
        setTimeout(randomFirecracker, nextDelay);
    }

    // 创建灯笼粒子效果
    function createLanternParticles(x, y, count = 10) {
        for (let i = 0; i &lt; count; i++) {
            const particle = document.createElement('div');
            particle.className = 'lantern-particle';

            particle.style.left = `${x}px`;
            particle.style.top = `${y}px`;

            // 随机运动方向
            const px = (Math.random() - 0.5) * 200;
            const py = (Math.random() - 0.5) * 200;
            particle.style.setProperty('--px', `${px}px`);
            particle.style.setProperty('--py', `${py}px`);

            // 随机大小
            const size = Math.random() * 3 + 3;
            particle.style.width = `${size}px`;
            particle.style.height = `${size}px`;

            // 随机动画时间
            const duration = Math.random() * 2 + 3;
            particle.style.animationDuration = `${duration}s`;

            document.body.appendChild(particle);

            // 动画结束后移除
            setTimeout(() =&gt; {
                particle.remove();
            }, duration * 1000);
        }
    }

    // 创建灯笼光晕效果
    function createLightEffect(x, y) {
        const light = document.createElement('div');
        light.className = 'light-effect';
        light.style.left = `${x - 100}px`;
        light.style.top = `${y - 100}px`;
        document.body.appendChild(light);

        // 淡出效果
        setTimeout(() =&gt; {
            light.style.opacity = '0';
            light.style.transition = 'opacity 1s';

            // 移除元素
            setTimeout(() =&gt; {
            light.remove();
            }, 1000);
        }, 800);
    }

    // 创建灯笼点击效果
    function createClickEffect(x, y) {
        const effect = document.createElement('div');
        effect.className = 'click-effect';
        effect.style.left = `${x - 25}px`;
        effect.style.top = `${y - 25}px`;
        document.body.appendChild(effect);

        // 创建粒子效果
        createLanternParticles(x, y, 20);

        // 动画结束后移除
        setTimeout(() =&gt; {
            effect.remove();
        }, 1000);
    }

    // 创建灯笼
    const createLantern = (boxClass, text) =&gt; {
        const box = document.createElement('div');
        box.className = boxClass;

        const deng = document.createElement('div');
        deng.className = 'deng';

        const xian = document.createElement('div');
        xian.className = 'xian';

        const dengA = document.createElement('div');
        dengA.className = 'deng-a';

        const dengB = document.createElement('div');
        dengB.className = 'deng-b';

        const dengT = document.createElement('div');
        dengT.className = 'deng-t';
        dengT.innerText = text;

        const shuiA = document.createElement('div');
        shuiA.className = 'shui shui-a';

        const shuiC = document.createElement('div');
        shuiC.className = 'shui-c';

        const shuiB = document.createElement('div');
        shuiB.className = 'shui-b';

        dengB.appendChild(dengT);
        dengA.appendChild(dengB);
        shuiA.appendChild(shuiC);
        shuiA.appendChild(shuiB);
        deng.appendChild(xian);
        deng.appendChild(dengA);
        deng.appendChild(shuiA);
        box.appendChild(deng);

        // 添加灯笼点击事件
        deng.addEventListener('click', (e) =&gt; {
            createClickEffect(e.clientX, e.clientY);
            createLightEffect(e.clientX, e.clientY);
            createFirecrackerExplosion(e.clientX, e.clientY);
        });

        // 初始粒子效果
        const initialX = box.offsetLeft + 70;
        const initialY = box.offsetTop + 55;
        createLanternParticles(initialX, initialY, 10);
        setInterval(() =&gt; {
            createLanternParticles(initialX, initialY, 5);
        }, 4000);

        document.body.appendChild(box);

        // 为灯笼添加光晕效果
        createLightEffect(initialX, initialY);
    };

    // 创建灯笼1 (春)
    createLantern('deng-box', '春');

    // 创建灯笼2 (节)
    createLantern('deng-box1', '节');

    // 添加节日祝福语
    const greeting = document.createElement('div');
    greeting.className = 'greeting';
    greeting.textContent = '新春快乐 万事如意';
    document.body.appendChild(greeting);

    // 创建高亮节日文字
    createFestivalTexts();

    // 开始随机鞭炮爆炸
    setTimeout(randomFirecracker, 2000);

    // 持续更新节日文字位置
    setInterval(() =&gt; {
        // 移除屏幕外的文字
        document.querySelectorAll('.festival-text').forEach(text =&gt; {
            const rect = text.getBoundingClientRect();
            if (rect.right &lt; 0 || rect.bottom &lt; 0 || 
                rect.left &gt; window.innerWidth || rect.top &gt; window.innerHeight) {
                text.remove();
            }
        });

        // 补充新的文字
        const currentCount = document.querySelectorAll('.festival-text').length;
        if (currentCount &lt; 15) {
            createFestivalTexts();
        }
    }, 5000);
})();</code></pre>]]></description>
    <pubDate>Sun, 27 Apr 2025 16:53:38 +0800</pubDate>
    <dc:creator>cesii</dc:creator>
    <guid>https://www.cesii.cn/js/10.html</guid>
</item>
<item>
    <title>意想不到的惊喜-某网站身份未授权漏洞</title>
    <link>https://www.cesii.cn/web-safe/114.html</link>
    <description><![CDATA[<p>好久没登录的x网站忘记了密码，想着找回下结果发现了意向不到的惊喜。</p>
<p>正常逻辑下，当用户找回密码时会将找回地址发送到对应的邮箱中，然后通过邮件中的找回地址重新设置，</p>
<p>实际上发现邮箱并没有收到邮件，而是将找回信息直接暴露在网页上，可以直接通过上面的找回地址重置用户名的密码，按照此方式只要知道网站的已知用户邮箱就可以做到重置其他用户的密码了。<br />
<a href="https://cesii.cn/content/uploadfile/202502/a2861738978244.png"><img src="https://cesii.cn/content/uploadfile/202502/a2861738978244.png" alt="" /></a><br />
<a href="https://cesii.cn/content/uploadfile/202502/12851738978266.png"><img src="https://cesii.cn/content/uploadfile/202502/12851738978266.png" alt="" /></a><br />
漏洞已反馈至网站负责人<br />
<a href="https://cesii.cn/content/uploadfile/202502/b3171738978305.png"><img src="https://cesii.cn/content/uploadfile/202502/b3171738978305.png" alt="" /></a></p>]]></description>
    <pubDate>Fri, 07 Feb 2025 23:10:47 +0800</pubDate>
    <dc:creator>cesii</dc:creator>
    <guid>https://www.cesii.cn/web-safe/114.html</guid>
</item>
<item>
    <title>JMeter中使用“Multipart/from-data”和不使用“Multipart/from-data”区别</title>
    <link>https://www.cesii.cn/jmeter/113.html</link>
    <description><![CDATA[<p>近期项目实施中遇到了此类问题，在接口调试中有一个选项叫<code>Use Multipart/from-data</code>,<br />
<a href="https://cesii.cn/content/uploadfile/202412/765c1734017467.png"><img src="https://cesii.cn/content/uploadfile/202412/765c1734017467.png" alt="" /></a><br />
默认情况下这个选项是不勾选的，请求后发现数据返回不对<br />
<a href="https://cesii.cn/content/uploadfile/202412/4d631734017542.png"><img src="https://cesii.cn/content/uploadfile/202412/4d631734017542.png" alt="" /></a><br />
此时request请求数据如下：<br />
<a href="https://cesii.cn/content/uploadfile/202412/c2151734017750.png"><img src="https://cesii.cn/content/uploadfile/202412/c2151734017750.png" alt="" /></a><br />
勾选<code>Use Multipart/from-data</code>后,发现数据返回正常了<br />
<a href="https://cesii.cn/content/uploadfile/202412/a74a1734017907.png"><img src="https://cesii.cn/content/uploadfile/202412/a74a1734017907.png" alt="" /></a><br />
此时request请求数据如下：<br />
<a href="https://cesii.cn/content/uploadfile/202412/5f461734017960.png"><img src="https://cesii.cn/content/uploadfile/202412/5f461734017960.png" alt="" /></a></p>
<p>发现第一次未勾选<code>Use Multipart/from-data</code>传参是按照url格式进行的，而勾选<code>Use Multipart/from-data</code>后发现传参是一段一段的，而且其中还带有其他参数，查了下二者含义，区别如下：</p>
<h3>1、数据编码方式</h3>
<h5>不使用 <code>multipart/form-data</code>：</h5>
<p>数据通常以 URL 编码（<code>application/x-www-form-urlencoded</code>）的形式发送。<br />
这种编码方式适用于纯文本数据，比如登录表单中的用户名和密码。<br />
数据会被转换成键值对的形式，如 <code>key1=value1&amp;key2=value2</code>。</p>
<h5>使用 <code>multipart/form-data</code>：</h5>
<p>数据被编码为多个部分（每个部分代表一个字段），每个部分之间由边界符分隔。<br />
这种编码方式支持上传文件和其他二进制数据。<br />
每个部分可以包含不同的内容类型，如文本、图片、视频等。</p>
<h3>2. 适用场景</h3>
<h5>不使用 <code>multipart/form-data</code>：</h5>
<p>适用于简单的表单提交，其中所有数据都是文本形式。<br />
不适合上传文件或其他二进制数据。</p>
<h5>使用 <code>multipart/form-data</code>：</h5>
<p>适用于需要上传文件的场景，比如文件上传功能。<br />
也适用于需要发送复杂数据结构的情况，如包含文件和文本信息的表单。</p>
<p>关于边界符、格式：<br />
（<strong>边界分隔符作用主要是为了区分不同部分的特殊字符串，起到分隔作用</strong>）<br />
--boundary_string<br />
Content-Disposition: form-data; name=&quot;description&quot;</p>
<pre><code>这是文件描述
--boundary_string
Content-Disposition: form-data; name="file"; filename="example.txt"
Content-Type: text/plain

... 文件内容 ...
--boundary_string--</code></pre>
<p>总结起来就是，当抓包请求时发现请求格式带有以上边界形式的数据时，在JMeter中记得把<code>Use Multipart/from-data</code>勾选就可以了。</p>]]></description>
    <pubDate>Thu, 12 Dec 2024 23:18:33 +0800</pubDate>
    <dc:creator>cesii</dc:creator>
    <guid>https://www.cesii.cn/jmeter/113.html</guid>
</item>
<item>
    <title>Python3报错：from urllib import unquote ImportError: cannot import name 'unquote' from 'urllib' (/usr/lib/python3.11/urllib/__init__.py)</title>
    <link>https://www.cesii.cn/python/1.html</link>
    <description><![CDATA[<p>在 Python 3 中，unquote 函数已被移至 <code>urllib.parse</code>模块。需要将.py文件中的<code>from urllib import unquote</code>改成<code>from urllib.parse import unquote</code><br />
<a href="https://cesii.cn/content/uploadfile/202411/a9f11730730983.png"><img src="https://cesii.cn/content/uploadfile/202411/a9f11730730983.png" alt="" /></a></p>]]></description>
    <pubDate>Mon, 04 Nov 2024 22:33:28 +0800</pubDate>
    <dc:creator>cesii</dc:creator>
    <guid>https://www.cesii.cn/python/1.html</guid>
</item>
<item>
    <title>Python3报错：from StringIO import StringIO ModuleNotFoundError: No module named 'StringIO'</title>
    <link>https://www.cesii.cn/python/111.html</link>
    <description><![CDATA[<p>在 Python 3 中，StringIO 模块已经被移到了 io 模块中。在 Python 2 中，StringIO 是一个独立的模块，<br />
如果用的 Python 3版本，编辑.py文件，将文件中的<code>from StringIO import StringIO</code>改为<code>from io import StringIO</code><br />
<a href="https://cesii.cn/content/uploadfile/202411/920e1730730496.png"><img src="https://cesii.cn/content/uploadfile/202411/920e1730730496.png" alt="" /></a></p>]]></description>
    <pubDate>Mon, 04 Nov 2024 22:23:35 +0800</pubDate>
    <dc:creator>cesii</dc:creator>
    <guid>https://www.cesii.cn/python/111.html</guid>
</item>
</channel>
</rss>