通过代理方式修改 JavaScript 获取到的 accept-language 和 user-agent
// ==UserScript==
// @name 抖音风控绕过
// @namespace http://tampermonkey.net/
// @version 1.0
// @description 通过代理方式修改 JavaScript 获取到的 accept-language 和 user-agent
// @author You
// @match *://*.douyin.com/*
// @grant none
// @run-at document-start
// @license MIT
// ==/UserScript==
(async function() {
'use strict';
// 固定的值
const FIXED_ACCEPT_LANGUAGE = 'zh-CN,zh';
const FIXED_USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) douyin/4.4.202 Chrome/104.0.5112.102 Electron/20.1.0-tt.4.release.douyin.195 TTElectron/20.1.0-tt.4.release.douyin.195 Safari/537.36 awemePcClient/4.4.202 buildId/12034427 osName/Windows';
console.log("记得自己改请求头语言和UA");
// 保存原始的 navigator 对象
const originalNavigator = navigator;
// 创建一个新的 navigator 对象代理
const navigatorProxy = new Proxy(originalNavigator, {
get: function(target, prop) {
// 拦截 acceptLanguage 属性
if (prop === 'language' || prop === 'languages') {
if (prop === 'language') {
return FIXED_ACCEPT_LANGUAGE.split(',')[0];
} else if (prop === 'languages') {
return FIXED_ACCEPT_LANGUAGE.split(',');
}
}
// 拦截 userAgent 属性
if (prop === 'userAgent') {
return FIXED_USER_AGENT;
}
// 拦截其他属性
const value = target[prop];
if (typeof value === 'function') {
return value.bind(target);
}
return value;
}
});
// 通过 Object.defineProperty 重新定义 navigator
try {
Object.defineProperty(window, 'navigator', {
value: navigatorProxy,
writable: false,
configurable: false
});
} catch (e) {
console.warn('无法重新定义 navigator:', e);
}
// 重写 Navigator.prototype 的相关属性
try {
Object.defineProperty(Navigator.prototype, 'userAgent', {
get: function() {
return FIXED_USER_AGENT;
},
configurable: false,
enumerable: true
});
Object.defineProperty(Navigator.prototype, 'language', {
get: function() {
return FIXED_ACCEPT_LANGUAGE.split(',')[0];
},
configurable: false,
enumerable: true
});
Object.defineProperty(Navigator.prototype, 'languages', {
get: function() {
return FIXED_ACCEPT_LANGUAGE.split(',');
},
configurable: false,
enumerable: true
});
} catch (e) {
console.warn('无法修改 Navigator.prototype:', e);
}
// 拦截 Intl 对象的相关方法
try {
const originalResolvedOptions = Intl.DateTimeFormat.prototype.resolvedOptions;
Intl.DateTimeFormat.prototype.resolvedOptions = function() {
const result = originalResolvedOptions.call(this);
result.locale = FIXED_ACCEPT_LANGUAGE.split(',')[0];
return result;
};
} catch (e) {
console.warn('无法修改 Intl.DateTimeFormat:', e);
}
// 创建一个更全面的代理对象来处理可能的检测
const handler = {
get: function(target, prop) {
if (prop === 'navigator') {
return navigatorProxy;
}
return target[prop];
}
};
// 尝试代理 window 对象
try {
const windowProxy = new Proxy(window, handler);
// 这里不直接替换 window,因为可能会导致问题
// 而是通过其他方式增强检测绕过
} catch (e) {
console.warn('无法创建 window 代理:', e);
}
console.log('Accept-Language 和 User-Agent 修改完成');
console.log('当前 User-Agent:', navigator.userAgent);
console.log('当前 Language:', navigator.language);
})();