@wxthank 有油猴脚本可以自动切换,我刚刚让ai做了一个,你们复制粘贴去油猴里新建一个就好。我也是一直手动切换旧版,刚才遭不住让ai写了个
// ==UserScript==
// @name 115.com 自动切换旧版 UI
// @namespace https://115.com
// @version 1.0.1
// @description 检测到 115.com 新版 UI 时自动跳转到旧版,在页面加载前完成切换,无闪烁
// @author ai
// @match https://115.com/*
// @match https://www.115.com/*
// @grant none
// @run-at document-start
// @license MIT
// ==/UserScript==
(function () {
'use strict';
// 油猴脚本无法在主文档请求发出前拦截网络层,这里尽量在 document-start
// 阶段完成跳转,并拦截客户端路由,避免用户看到新版 UI。
const ROOT_HOSTS = new Set(['115.com', 'www.115.com']);
const NEW_UI_PATH_RE = /^\/storage(?:\/|$)/;
const STORAGE_KEY = '__115_old_ui_redirect';
const REDIRECT_TTL_MS = 2000;
function isRootHost(hostname) {
return ROOT_HOSTS.has(hostname);
}
function isNewUIPath(pathname) {
return NEW_UI_PATH_RE.test(pathname);
}
function readRedirectState() {
try {
const raw = sessionStorage.getItem(STORAGE_KEY);
return raw ? JSON.parse(raw) : null;
} catch {
return null;
}
}
function writeRedirectState(sourceUrl, targetUrl) {
try {
sessionStorage.setItem(STORAGE_KEY, JSON.stringify({
sourceUrl,
targetUrl,
ts: Date.now(),
}));
} catch {}
}
function clearRedirectState() {
try {
sessionStorage.removeItem(STORAGE_KEY);
} catch {}
}
function shouldSkipRedirect(sourceUrl, targetUrl) {
const state = readRedirectState();
if (!state) return false;
if (Date.now() - state.ts > REDIRECT_TTL_MS) return false;
return state.sourceUrl === sourceUrl && state.targetUrl === targetUrl;
}
function toRedirectUrl(url) {
if (url.origin === location.origin) {
return `${url.pathname}${url.search}${url.hash}`;
}
return url.toString();
}
function normalizeUrl(url) {
if (typeof url === 'string' || url instanceof URL) {
try {
return new URL(url, location.href);
} catch {
return null;
}
}
return null;
}
/**
* 将新版 UI URL 转换为旧版 URL
* /storage → /?cid=0&offset=0&mode=wangpan
* /storage/allfiles?cid=123 → /?cid=123&offset=0&mode=wangpan
*/
function toOldUIUrl(url) {
const u = normalizeUrl(url);
if (!u || !isRootHost(u.hostname) || !isNewUIPath(u.pathname)) return null;
const params = new URLSearchParams(u.search);
if (!params.has('cid')) {
params.set('cid', '0');
}
if (!params.has('offset')) {
params.set('offset', '0');
}
if (!params.has('mode')) {
params.set('mode', 'wangpan');
}
u.pathname = '/';
u.search = params.toString();
return u.toString();
}
/**
* 检查是否需要跳转到旧版
*/
function shouldRedirect() {
if (!isRootHost(location.hostname)) {
return false;
}
if (!isNewUIPath(location.pathname)) {
return false;
}
return true;
}
function redirectToOldUI(url, useReplace) {
const sourceUrl = normalizeUrl(url);
const oldUrl = toOldUIUrl(url);
if (!sourceUrl || !oldUrl) return false;
if (shouldSkipRedirect(sourceUrl.toString(), oldUrl)) return false;
writeRedirectState(sourceUrl.toString(), oldUrl);
if (useReplace) {
location.replace(oldUrl);
} else {
location.assign(oldUrl);
}
return true;
}
if (!isNewUIPath(location.pathname)) {
clearRedirectState();
}
// ─── 立即执行:在页面渲染前跳转 ───
if (shouldRedirect() && redirectToOldUI(location.href, true)) {
return;
}
// ─── 拦截 history API 防止 Next.js 路由回新版 ───
const _pushState = history.pushState;
const _replaceState = history.replaceState;
function interceptUrl(url) {
const fullUrl = normalizeUrl(url);
if (!fullUrl) return url;
const oldUrl = toOldUIUrl(fullUrl);
if (oldUrl) {
return toRedirectUrl(new URL(oldUrl));
}
return url;
}
history.pushState = function (state, title, url) {
return _pushState.call(this, state, title, interceptUrl(url));
};
history.replaceState = function (state, title, url) {
return _replaceState.call(this, state, title, interceptUrl(url));
};
// ─── 拦截 <a> 标签点击(处理 Next.js 客户端导航) ───
document.addEventListener('click', function (e) {
if (e.defaultPrevented || e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) {
return;
}
if (!(e.target instanceof Element)) {
return;
}
const link = e.target.closest('a[href]');
if (!link) return;
if (link.target && link.target !== '_self') return;
if (link.hasAttribute('download')) return;
const href = link.getAttribute('href');
if (!href) return;
const fullUrl = normalizeUrl(href);
if (!fullUrl) return;
if (!isRootHost(fullUrl.hostname) || !isNewUIPath(fullUrl.pathname)) return;
e.preventDefault();
e.stopPropagation();
redirectToOldUI(fullUrl, false);
}, true);
})();