您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
为 NovelAI 图片解析器启用腾讯云和百度翻译 API 跨域支持
// ==UserScript== // @name NovelAI 翻译工具 CORS 支持 // @namespace http://tampermonkey.net/ // @version 1.0.0 // @description 为 NovelAI 图片解析器启用腾讯云和百度翻译 API 跨域支持 // @author 夏影 // @match https://toys.senriakane.com/novelai-prompt-reader/* // @match *://*/*novelai*prompt*reader* // @grant GM_xmlhttpRequest // @grant unsafeWindow // @run-at document-start // @license MIT // @homepage https://github.com/Natsukage/novelai-prompt-reader // ==/UserScript== (function () { 'use strict'; // CORS 支持脚本已加载 // 需要代理的翻译API域名 const TRANSLATION_APIS = [ 'tmt.tencentcloudapi.com', // 腾讯云翻译 'fanyi-api.baidu.com' // 百度翻译 ]; // 检查URL是否是翻译API function isTranslationAPI(url) { try { const urlObj = new URL(url); return TRANSLATION_APIS.some(api => urlObj.hostname === api); } catch (e) { return false; } } // 将Headers对象转换为普通对象 function headersToObject(headers) { const result = {}; if (headers instanceof Headers) { for (const [key, value] of headers.entries()) { result[key] = value; } } else if (headers && typeof headers === 'object') { Object.assign(result, headers); } return result; } // 使用GM_xmlhttpRequest发送请求 function makeGMRequest(url, options) { return new Promise((resolve, reject) => { const headers = headersToObject(options.headers || {}); // 构建GM_xmlhttpRequest参数 const gmOptions = { method: options.method || 'GET', url: url, headers: headers, data: options.body, timeout: 30000, onload: function (response) { // 创建Response-like对象 const responseObj = { ok: response.status >= 200 && response.status < 300, status: response.status, statusText: response.statusText, headers: new Headers(), text: () => Promise.resolve(response.responseText), json: () => { try { return Promise.resolve(JSON.parse(response.responseText)); } catch (e) { return Promise.reject(new Error('Invalid JSON response')); } } }; // 解析响应头 if (response.responseHeaders) { response.responseHeaders.split('\r\n').forEach(header => { const parts = header.split(': '); if (parts.length === 2) { responseObj.headers.set(parts[0], parts[1]); } }); } resolve(responseObj); }, onerror: function (error) { reject(new Error(`网络请求失败: ${error.error || '未知错误'}`)); }, ontimeout: function () { reject(new Error('请求超时')); } }; GM_xmlhttpRequest(gmOptions); }); } // 拦截并代理fetch请求 const originalFetch = unsafeWindow.fetch; unsafeWindow.fetch = function (url, options = {}) { const urlString = url.toString(); // 检查是否是翻译API请求 if (isTranslationAPI(urlString)) { return makeGMRequest(urlString, options); } // 对于非翻译API请求,使用原始fetch return originalFetch.apply(this, arguments); }; // 为了确保脚本在页面加载完成后也能工作,监听DOM变化 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', function () { // CORS 支持已就绪 }); } // 添加页面通知 function showNotification() { // 等待页面加载完成 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', showNotification); return; } // 创建通知元素 const notification = document.createElement('div'); notification.innerHTML = ` <div style=" position: fixed; top: 20px; right: 20px; background: #28a745; color: white; padding: 12px 20px; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.15); z-index: 10000; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; font-size: 14px; max-width: 300px; transition: all 0.3s ease; " id="corsNotification"> ✅ CORS 支持已启用<br> <small style="opacity: 0.9;">腾讯云和百度翻译可正常使用</small> </div> `; document.body.appendChild(notification); // 3秒后自动隐藏 setTimeout(() => { const elem = document.getElementById('corsNotification'); if (elem) { elem.style.opacity = '0'; elem.style.transform = 'translateY(-20px)'; setTimeout(() => { if (elem.parentNode) { elem.parentNode.removeChild(elem); } }, 300); } }, 3000); } // 显示通知 showNotification(); // 添加全局标识,表示CORS支持已启用 unsafeWindow.NOVELAI_CORS_ENABLED = true; })();