水印问题的本质与解决思路
豆包AI生成图片时,平台会在图片上添加水印,这是行业内常见的做法。但通过分析前端数据流,发现一个有趣的现象:服务器返回的JSON数据中,实际上同时包含了无水印的原图URL和有水印的URL。前端界面默认展示和下载的是带水印版本,但原始数据已经悄然抵达浏览器环境。
这一发现成为了解决问题的关键。与其费力地处理已生成的图片水印,不如在数据流动过程中进行干预,将前端默认使用的水印URL替换为无水印原图URL。这种思路类似于在物流配送中心更换包裹内容,而非在包裹送达后费力拆解。

脚本核心技术解析
该脚本的实现主要依赖几个关键技术点,这些代码设计展现了一种深度介入前端数据流的能力。
JSON.parse钩子:拦截数据流
脚本最核心的部分是重写了浏览器原生的JSON.parse方法,这是一种经典的钩子技术。通过保存原始JSON.parse引用,然后将其替换为自定义函数,脚本得以在数据解析阶段介入:
javascript
let _parse = JSON.parse;
JSON.parse = function(data) {
let jsonData = _parse(data);
// ...数据处理逻辑
return jsonData;
}
这种实现方式确保了脚本不会破坏原有的JSON解析功能,只是在解析前后添加了自定义逻辑。每当豆包前端代码调用JSON.parse解析服务器返回的数据时,我们的替换函数就会率先获得处理机会。
递归搜索算法:精准定位目标数据
脚本中的findAllKeysInJson函数采用递归算法,能够遍历整个JSON对象,无论数据结构嵌套多深,都能准确找出所有包含图片信息的"creations"字段。这种深度搜索确保了即使豆包前端数据结构发生变化,只要保留creations字段,脚本就能继续生效。
递归算法的设计值得细究:它首先检查当前对象是否包含目标键,如果找到就将对应值存入结果数组。然后继续遍历对象的每个属性或数组的每个元素,确保不遗漏任何嵌套层级中的数据。
URL替换逻辑:实现去水印关键
一旦找到creations数据,脚本会遍历其中的每个图片项,并进行关键操作:
javascript
const rawUrl = item.image.image_ori_raw.url;
item.image.image_ori.url = rawUrl;
这里,image_ori_raw.url代表无水印原图,而image_ori.url则是前端默认使用的水印版本。通过将后者指向前者,脚本实现了水印的去除。这种替换操作直接在数据层面完成,前端组件在不知情的情况下使用了无水印版本。
值得注意的是,脚本作者还细心地替换了预览图和缩略图的URL,确保在图片预览阶段也能看到无水印效果。这种细节处理提升了用户体验的一致性。
为脚本添加用户感知提示
一个技术优秀的工具如果缺乏用户反馈,会让人难以确认其是否正常工作。为此,需要为脚本添加清晰的状态提示机制。
提示方案设计考虑
在设计用户提示时,需要考虑几个关键因素:提示应明显但不过分干扰,需要确保只在脚本实际执行操作时显示,并且应当提供足够的上下文信息。基于这些考虑,可以采用以下几种提示方案。
浮动提示框方案:在页面角落显示一个临时性的浮动提示框,几秒后自动消失。这种方式视觉冲击力强,适合首次使用时的确认。
javascript
function showFloatingToast() {
const toast = document.createElement('div');
toast.textContent = '豆包AI去水印脚本已激活,已成功拦截并替换水印URL';
toast.style.cssText = 'position:fixed; top:20px; right:20px; background:#4CAF50; color:white; padding:12px; border-radius:4px; z-index:10000; box-shadow:0 4px 8px rgba(0,0,0,0.2);';
document.body.appendChild(toast);
setTimeout(() => {
document.body.removeChild(toast);
}, 3000);
}
状态栏消息方案:在页面顶部或底部添加一个不显眼的状态栏,显示脚本状态。这种方式干扰小,适合长期使用。
控制台日志方案:同时输出控制台日志,方便技术用户调试和验证。
提示触发逻辑优化
提示信息应当在脚本检测到creations数据并成功替换URL后显示。这意味着需要修改原有的JSON.parse函数,在完成替换操作后触发提示:
javascript
JSON.parse = function(data) {
let jsonData = _parse(data);
if (!data.match('creations')) return jsonData;
let creations = findAllKeysInJson(jsonData, 'creations');
if (creations.length > 0) {
// ...执行现有的URL替换逻辑...
showFloatingToast(); // 添加提示
}
return jsonData;
};
集成用户提示的完整代码
将上述提示机制整合到原脚本中,得到以下完整实现:
javascript
// ==UserScript==
// @name 豆包AI生图去水印(增强版)
// @namespace http://tampermonkey.net/
// @version 1.2.0
// @description 豆包AI生图下载原图去水印,并添加用户提示
// @author mzh
// @homepage https://blog.csdn.net/u011027547
// @match https://www.doubao.com/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=doubao.com
// @grant none
// @license GPL-3.0
// @downloadURL https://update.greasyfork.org/scripts/558800/%E8%B1%86%E5%8C%85AI%E7%94%9F%E5%9B%BE%E5%8E%BB%E6%B0%B4%E5%8D%B0%EF%BC%88%E5%A2%9E%E5%BC%BA%E7%89%88%EF%BC%89.user.js
// @updateURL https://update.greasyfork.org/scripts/558800/%E8%B1%86%E5%8C%85AI%E7%94%9F%E5%9B%BE%E5%8E%BB%E6%B0%B4%E5%8D%B0%EF%BC%88%E5%A2%9E%E5%BC%BA%E7%89%88%EF%BC%89.meta.js
// ==/UserScript==
(function() {
'use strict';
let scriptActive = false;
function showActivationMessage() {
// 避免重复提示
if (scriptActive) return;
scriptActive = true;
// 控制台日志
console.log('🚫 豆包AI去水印脚本已激活,正在监控图片数据...');
// 页面顶部状态栏
const statusBar = document.createElement('div');
statusBar.textContent = '豆包AI去水印:已启用(检测到图片生成时会自动去除水印)';
statusBar.style.cssText = `
position: fixed;
top: 0;
left: 0;
width: 100%;
background: #4CAF50;
color: white;
padding: 8px;
text-align: center;
font-size: 14px;
z-index: 9999;
box-shadow: 0 2px 5px rgba(0,0,0,0.2);
`;
document.body.appendChild(statusBar);
// 5秒后淡出状态栏
setTimeout(() => {
statusBar.style.transition = 'opacity 0.5s';
statusBar.style.opacity = '0';
setTimeout(() => {
if (document.body.contains(statusBar)) {
document.body.removeChild(statusBar);
}
}, 500);
}, 5000);
}
function showSuccessToast() {
const toast = document.createElement('div');
toast.innerHTML = '✅ 已成功去除图片水印,可下载无水印原图';
toast.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
background: #2196F3;
color: white;
padding: 12px 16px;
border-radius: 4px;
z-index: 10000;
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
font-size: 14px;
max-width: 300px;
`;
document.body.appendChild(toast);
setTimeout(() => {
if (document.body.contains(toast)) {
toast.style.transition = 'opacity 0.5s';
toast.style.opacity = '0';
setTimeout(() => {
if (document.body.contains(toast)) {
document.body.removeChild(toast);
}
}, 500);
}
}, 3000);
}
function findAllKeysInJson(obj, key) {
const results = [];
function search(current) {
if (current && typeof current === 'object') {
if (!Array.isArray(current) && Object.prototype.hasOwnProperty.call(current, key)) {
results.push(current[key]);
}
const items = Array.isArray(current) ? current : Object.values(current);
for (const item of items) {
search(item);
}
}
}
search(obj);
return results;
}
let _parse = JSON.parse;
JSON.parse = function(data) {
let jsonData = _parse(data);
if (!data.match('creations')) return jsonData;
let creations = findAllKeysInJson(jsonData, 'creations');
if (creations.length > 0) {
creations.forEach((creation) => {
creation.map((item) => {
if (item.image && item.image.image_ori_raw && item.image.image_ori_raw.url) {
const rawUrl = item.image.image_ori_raw.url;
item.image.image_ori.url = rawUrl;
// 预览时也去水印
item.image.image_preview.url = rawUrl;
item.image.image_thumb.url = rawUrl;
}
return item;
});
});
// 显示成功提示
setTimeout(showSuccessToast, 500);
}
return jsonData;
}
// 页面加载后显示激活提示
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', showActivationMessage);
} else {
setTimeout(showActivationMessage, 1000);
}
})();
豆包AI生图去水印(增强版)
🚀 一键自动去除豆包AI生成图片的水印,直接下载高清无水印原图!本脚本通过安全、非侵入式的技术方案,在后台静默处理图片数据,为您提供纯净的AI绘画体验。
功能亮点
• 自动去水印:监控豆包AI的生图过程,自动识别并替换带水印的图片为原始无水印版本。
• 全面覆盖:处理生成的原图(image_ori)、预览图(image_preview)及缩略图(image_thumb),确保您在查看和下载时均获得无水印图片。
• 用户友好提示:
◦ 脚本激活提示:页面加载后,顶部会显示绿色状态栏,提示脚本已启用。
◦ 去水印成功提示:当检测到新图片生成并成功去除水印后,页面右下角会弹出蓝色提示框。
• 纯净安全:脚本仅操作图片数据,声明 @grant none 权限,不请求任何敏感API,不会将您的任何数据发送至第三方服务器。
• 低调静默:除必要的用户提示外,脚本在后台运行,不影响您正常使用豆包AI的其他功能。
使用方法
- 安装脚本:在脚本管理平台点击安装,Tampermonkey等油猴脚本管理器会自动识别并加载。
- 访问豆包AI:打开豆包AI的生图页面(例如 https://www.doubao.com/\*)。
- 正常生图:像往常一样输入提示词生成图片。
- 下载原图:图片生成后,脚本会自动处理水印。使用豆包AI原有的下载功能,即可保存无水印原图。
脚本运行后,您会看到如下提示:
• 页面加载时,顶部出现绿色状态栏,显示"豆包AI去水印:已启用..."。
• 每次成功生成图片后,右下角会弹出"✅ 已成功去除图片水印,可下载无水印原图"的提示。
技术原理
脚本通过重写 JSON.parse 方法,监控页面中的数据流。当检测到包含图片生成信息(如 creations 字段)的JSON数据时,会自动查找其中的原始图片URL(image_ori_raw.url),并用它替换掉带水印的图片URL。这个过程在数据层面完成,高效且无需修改页面布局。
常见问题
Q:脚本会影响豆包AI的其他功能吗?
A: 不会。脚本只针对图片数据URL进行替换,完全不影响文本对话、模型选择等所有其他功能。
Q:安装后为什么没有效果?
A: 请确保:
• 脚本已正确启用(Tampermonkey面板中该脚本开关为绿色)。
• 您访问的网址匹配 https://www.doubao.com/\*。
• 豆包AI的生图功能本身工作正常。如果问题依旧,请尝试刷新页面或检查浏览器控制台是否有错误信息。
Q:这个脚本安全吗?
A: 本脚本开源,代码透明。它仅运行在指定的豆包AI页面上,用于替换图片URL,不收集任何用户信息,也不申请高风险权限,非常安全。
Q:豆包AI更新后脚本失效怎么办?
A: 作者会尽力维护脚本的兼容性。如果遇到失效,请关注脚本的更新发布。您也可以通过脚本页面向作者反馈。
更新日志
• v1.1.0:增强提示体验,添加去水印成功Toast;优化代码逻辑,提升稳定性。
• v1.0.0:初始版本,实现基础的去水印功能。
开发者信息
• 作者:mzh
• 反馈与支持:如有问题或建议,请在脚本发布页面留言。
免责声明:本脚本仅为个人学习与交流方便而开发,旨在提升用户体验。请尊重豆包AI的服务条款,并仅将下载的图片用于合法用途。
许可证信息
本脚本采用GPL-3.0开源许可证发布。这意味着您可以自由使用、修改和分发本脚本,但修改后的版本必须同样以GPL-3.0许可证开源,并保留原始的版权声明和作者信息
总结与使用展望
这一经过优化的豆包AI生图去水印脚本,通过拦截并替换前端数据流中的图片URL,巧妙地实现了水印去除功能。新增的用户提示机制使脚本的工作状态清晰可见,大大提升了用户体验。
从技术角度看,这种基于JSON.parse钩子的方法不仅适用于豆包AI,对其他存在类似数据结构的平台也有参考价值。核心思路是在数据解析阶段进行干预,而非在渲染完成后修改,这通常更为高效和稳定。
需要注意的是,这类脚本的有效性依赖于目标网站的前端数据结构。如果豆包未来更改其API响应格式,脚本可能需要相应调整。但在可预见的未来,这一解决方案应该能持续为使用者提供便捷的无水印图片下载体验。