好多论坛不支持传图,只能自己找图床然后用代码粘贴,不太方便,于是让 AI 写了俩脚本,直接在发帖处粘贴图片就能自动上传图床返回代码了。
直接把图片放 picgo 图床,进入 https://www.picgo.net/ 注册账号,登录之后点击设置 ——API,获取秘钥。
![图片[1]|在不能传图的论坛太麻烦了,自动传图|不死鸟资源网](https://www.busi.net/wp-content/uploads/2025/06/20250605110140486-image-1024x765.png)
下面是脚本
nodeseek:(原来已有相关脚本 https://www.nodeseek.com/post-74493-1)
// ==UserScript==
// @name NodeSeek 图片自动上传 (Markdown)
// @namespace http://tampermonkey.net/
// @version 1.5
// @description 在 NodeSeek 的发帖/回复编辑框中粘贴图片时自动上传到 PicGo 并插入 Markdown 图片
// @author dalao.net
// @match https://www.nodeseek.com/post-*
// @match https://www.nodeseek.com/new-discussion
// @grant GM_xmlhttpRequest
// @grant GM_addStyle
// ==/UserScript==
(function() {
'use strict';
const API_KEY = '';
const PICGO_API_URL = 'https://www.picgo.net/api/1/upload';
GM_addStyle(`
.uploading-overlay {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: rgba(0, 0, 0, 0.7);
color: white;
padding: 10px 20px;
border-radius: 4px;
z-index: 9999;
display: none;
font-family: Arial, sans-serif;
}
`);
const uploadingOverlay = document.createElement('div');
uploadingOverlay.className = 'uploading-overlay';
uploadingOverlay.textContent = '图片上传中...';
document.body.appendChild(uploadingOverlay);
document.addEventListener('paste', function(e) {
const editor = getCodeMirrorEditor();
if (!editor) return;
const items = (e.clipboardData || window.clipboardData).items;
for (let i = 0; i < items.length; i++) {
const item = items[i];
if (item.type.indexOf('image') !== -1) {
e.preventDefault();
showUploadingOverlay();
const blob = item.getAsFile();
uploadImage(blob).then(url => {
insertMarkdownImage(editor, url);
}).catch(err => {
alert('图片上传失败: ' + err.message);
console.error('上传错误:', err);
}).finally(hideUploadingOverlay);
break;
}
}
});
function showUploadingOverlay() {
uploadingOverlay.style.display = 'block';
}
function hideUploadingOverlay() {
uploadingOverlay.style.display = 'none';
}
function uploadImage(file) {
return new Promise((resolve, reject) => {
if (!file || !file.type.startsWith('image/')) {
return reject(new Error('无效的图片文件'));
}
const formData = new FormData();
formData.append('key', API_KEY);
formData.append('source', file);
GM_xmlhttpRequest({
method: 'POST',
url: PICGO_API_URL,
data: formData,
headers: {
'Accept': 'application/json',
'X-Requested-With': 'XMLHttpRequest'
},
onload: function(res) {
try {
const data = JSON.parse(res.responseText);
if (data.status_code === 200 && data.image?.url) {
resolve(data.image.url);
} else {
reject(new Error(data.error?.message || data.status_txt));
}
} catch (err) {
reject(new Error('解析响应失败: ' + err.message));
}
},
onerror: function(err) {
reject(new Error('网络错误: ' + err.status + ' ' + err.statusText));
},
ontimeout: function() {
reject(new Error('请求超时'));
}
});
});
}
function getCodeMirrorEditor() {
const cm6Editor = document.querySelector('.cm-editor');
if (cm6Editor) {
if (window.CodeMirror) {
return {
type: 'cm6',
instance: cm6Editor,
getDoc: () => cm6Editor.cmEditor.state.doc,
replaceSelection: (text) => {
const editor = cm6Editor.cmEditor;
const transaction = editor.state.update({
changes: {
from: editor.state.selection.main.from,
to: editor.state.selection.main.to,
insert: text
},
selection: {anchor: editor.state.selection.main.from + text.length}
});
editor.dispatch(transaction);
}
};
}
}
const cm5Editor = document.querySelector('.CodeMirror');
if (cm5Editor && cm5Editor.CodeMirror) {
return {
type: 'cm5',
instance: cm5Editor.CodeMirror,
getDoc: () => cm5Editor.CodeMirror.getDoc(),
replaceSelection: (text) => {
cm5Editor.CodeMirror.replaceSelection(text);
const cursor = cm5Editor.CodeMirror.getCursor();
cursor.ch += text.length;
cm5Editor.CodeMirror.setCursor(cursor);
}
};
}
if (window.CodeMirror && window.CodeMirror.instances && window.CodeMirror.instances.length > 0) {
return {
type: 'cm5',
instance: window.CodeMirror.instances[0],
getDoc: () => window.CodeMirror.instances[0].getDoc(),
replaceSelection: (text) => {
window.CodeMirror.instances[0].replaceSelection(text);
const cursor = window.CodeMirror.instances[0].getCursor();
cursor.ch += text.length;
window.CodeMirror.instances[0].setCursor(cursor);
}
};
}
console.warn('无法检测到CodeMirror编辑器');
return null;
}
function insertMarkdownImage(editor, url) {
if (!editor) {
console.warn('没有可用的编辑器实例');
return;
}
const imgTag = `\n\n`;
try {
editor.replaceSelection(imgTag);
if (editor.type === 'cm5') {
editor.instance.scrollIntoView(null, 20);
} else if (editor.type === 'cm6') {
const view = editor.instance.cmEditor;
view.dispatch({
effects: view.scrollIntoView(view.state.selection.main.to, { y: 'center' })
});
}
} catch (error) {
console.error('使用CodeMirror API插入内容失败:', error);
try {
const contentElement = editor.type === 'cm5'
? document.querySelector('.CodeMirror-code')
: document.querySelector('.cm-content');
if (contentElement) {
const textNode = document.createTextNode(imgTag);
if (contentElement.hasChildNodes()) {
contentElement.appendChild(textNode);
} else {
contentElement.appendChild(textNode);
}
const selection = window.getSelection();
const range = document.createRange();
range.selectNodeContents(contentElement);
range.collapse(false);
selection.removeAllRanges();
selection.addRange(range);
contentElement.scrollTop = contentElement.scrollHeight;
}
} catch (e) {
console.error('备选DOM操作方案也失败:', e);
alert('插入图片失败: 无法找到编辑器内容区域');
}
}
}
console.log('NodeSeek 图片上传脚本已激活(Markdown 格式)');
})();
yaohuo:
// ==UserScript==
// @name 妖火论坛图片自动上传
// @namespace http://tampermonkey.net/
// @version 1.5
// @description 在发帖编辑框中粘贴图片时自动上传到PicGo图床
// @author ID号:11123
// @match https://yaohuo.me/bbs/book_view_*.aspx*
// @match https://www.yaohuo.me/bbs/book_view_*.aspx*
// @match https://yaohuo.me/bbs/book_re.aspx?*
// @match https://yaohuo.me/bbs-*.html*
// @grant GM_xmlhttpRequest
// @grant GM_addStyle
// ==/UserScript==
(function() {
'use strict';
// PicGo API 配置
const API_KEY = '';
const PICGO_API_URL = 'https://www.picgo.net/api/1/upload';
GM_addStyle(`
.uploading-overlay {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: rgba(0, 0, 0, 0.7);
color: white;
padding: 10px 20px;
border-radius: 4px;
z-index: 9999;
display: none;
font-family: Arial, sans-serif;
}
`);
const uploadingOverlay = document.createElement('div');
uploadingOverlay.className = 'uploading-overlay';
uploadingOverlay.textContent = '图片上传中...';
document.body.appendChild(uploadingOverlay);
// 监听所有可能的编辑器
waitForElement('textarea[name="book_content"]', function(editor) {
editor.addEventListener('paste', handlePaste);
console.log('主编辑区图片自动上传脚本已激活');
});
waitForElement('textarea.retextarea[name="content"]', function(editor) {
editor.addEventListener('paste', handlePaste);
console.log('回复区图片自动上传脚本已激活');
});
function waitForElement(selector, callback, maxWaitTime = 10000) {
let startTime = new Date().getTime();
const checkElement = () => {
const element = document.querySelector(selector);
if (element) {
callback(element);
} else if (new Date().getTime() - startTime < maxWaitTime) {
setTimeout(checkElement, 100);
} else {
console.error('等待元素加载超时:', selector);
}
};
checkElement();
}
function handlePaste(e) {
const clipboardData = e.clipboardData || window.clipboardData;
const items = clipboardData.items;
if (items && items.length > 0) {
for (let i = 0; i < items.length; i++) {
const item = items[i];
if (item.type.indexOf('image') !== -1) {
e.preventDefault();
showUploadingOverlay();
const blob = item.getAsFile();
uploadImage(blob).then(url => {
insertImageToEditor(url, e.target);
}).catch(err => {
alert('图片上传失败: ' + err.message);
console.error('上传错误:', err);
}).finally(hideUploadingOverlay);
break;
}
}
}
}
function showUploadingOverlay() {
uploadingOverlay.style.display = 'block';
}
function hideUploadingOverlay() {
uploadingOverlay.style.display = 'none';
}
function uploadImage(file) {
return new Promise((resolve, reject) => {
if (!file || !file.type.startsWith('image/')) {
return reject(new Error('无效的图片文件'));
}
const formData = new FormData();
formData.append('key', API_KEY);
formData.append('source', file);
GM_xmlhttpRequest({
method: 'POST',
url: PICGO_API_URL,
data: formData,
headers: {
'Accept': 'application/json',
'X-Requested-With': 'XMLHttpRequest'
},
onload: function(res) {
try {
const data = JSON.parse(res.responseText);
if (data.status_code === 200 && data.image?.url) {
resolve(data.image.url);
} else {
reject(new Error(data.error?.message || data.status_txt));
}
} catch (err) {
reject(new Error('解析响应失败: ' + err.message));
}
},
onerror: function(err) {
reject(new Error('网络错误: ' + err.status + ' ' + err.statusText));
},
ontimeout: function() {
reject(new Error('请求超时'));
}
});
});
}
function insertImageToEditor(url, editor) {
if (!editor) return;
const start = editor.selectionStart;
const end = editor.selectionEnd;
const before = editor.value.substring(0, start);
const after = editor.value.substring(end);
const imgTag = `[img]${url}[/img]`;
editor.value = before + imgTag + after;
editor.selectionStart = editor.selectionEnd = start + imgTag.length;
const event = new Event('input', { bubbles: true });
editor.dispatchEvent(event);
}
})();
本站资源均为作者提供和网友推荐收集整理而来,仅供学习和研究使用,请在下载后24小时内删除,谢谢合作!
THE END