ACT.谷歌.DM.NCR

没有国家重定向,轻松切换区域/语言。

  1. // ==UserScript==
  2. // @name ACT.Google.DM.NCR
  3. // @name:zh-CN ACT.谷歌.DM.NCR
  4. // @description No country redirect, easy to switch region/language.
  5. // @description:zh-CN 没有国家重定向,轻松切换区域/语言。
  6. // @author ACTCD
  7. // @version 20231206.1
  8. // @license GPL-3.0-or-later
  9. // @namespace ACTCD/Userscripts
  10. // @supportURL https://github.com/ACTCD/Userscripts#contact
  11. // @homepageURL https://github.com/ACTCD/Userscripts
  12. // @match *://*.google.com/*
  13. // @match *://*.google.ad/*
  14. // @match *://*.google.ae/*
  15. // @match *://*.google.com.af/*
  16. // @match *://*.google.com.ag/*
  17. // @match *://*.google.com.ai/*
  18. // @match *://*.google.al/*
  19. // @match *://*.google.am/*
  20. // @match *://*.google.co.ao/*
  21. // @match *://*.google.com.ar/*
  22. // @match *://*.google.as/*
  23. // @match *://*.google.at/*
  24. // @match *://*.google.com.au/*
  25. // @match *://*.google.az/*
  26. // @match *://*.google.ba/*
  27. // @match *://*.google.com.bd/*
  28. // @match *://*.google.be/*
  29. // @match *://*.google.bf/*
  30. // @match *://*.google.bg/*
  31. // @match *://*.google.com.bh/*
  32. // @match *://*.google.bi/*
  33. // @match *://*.google.bj/*
  34. // @match *://*.google.com.bn/*
  35. // @match *://*.google.com.bo/*
  36. // @match *://*.google.com.br/*
  37. // @match *://*.google.bs/*
  38. // @match *://*.google.bt/*
  39. // @match *://*.google.co.bw/*
  40. // @match *://*.google.by/*
  41. // @match *://*.google.com.bz/*
  42. // @match *://*.google.ca/*
  43. // @match *://*.google.cd/*
  44. // @match *://*.google.cf/*
  45. // @match *://*.google.cg/*
  46. // @match *://*.google.ch/*
  47. // @match *://*.google.ci/*
  48. // @match *://*.google.co.ck/*
  49. // @match *://*.google.cl/*
  50. // @match *://*.google.cm/*
  51. // @match *://*.google.cn/*
  52. // @match *://*.google.com.co/*
  53. // @match *://*.google.co.cr/*
  54. // @match *://*.google.com.cu/*
  55. // @match *://*.google.cv/*
  56. // @match *://*.google.com.cy/*
  57. // @match *://*.google.cz/*
  58. // @match *://*.google.de/*
  59. // @match *://*.google.dj/*
  60. // @match *://*.google.dk/*
  61. // @match *://*.google.dm/*
  62. // @match *://*.google.com.do/*
  63. // @match *://*.google.dz/*
  64. // @match *://*.google.com.ec/*
  65. // @match *://*.google.ee/*
  66. // @match *://*.google.com.eg/*
  67. // @match *://*.google.es/*
  68. // @match *://*.google.com.et/*
  69. // @match *://*.google.fi/*
  70. // @match *://*.google.com.fj/*
  71. // @match *://*.google.fm/*
  72. // @match *://*.google.fr/*
  73. // @match *://*.google.ga/*
  74. // @match *://*.google.ge/*
  75. // @match *://*.google.gg/*
  76. // @match *://*.google.com.gh/*
  77. // @match *://*.google.com.gi/*
  78. // @match *://*.google.gl/*
  79. // @match *://*.google.gm/*
  80. // @match *://*.google.gr/*
  81. // @match *://*.google.com.gt/*
  82. // @match *://*.google.gy/*
  83. // @match *://*.google.hk/*
  84. // @match *://*.google.com.hk/*
  85. // @match *://*.google.hn/*
  86. // @match *://*.google.hr/*
  87. // @match *://*.google.ht/*
  88. // @match *://*.google.hu/*
  89. // @match *://*.google.co.id/*
  90. // @match *://*.google.ie/*
  91. // @match *://*.google.co.il/*
  92. // @match *://*.google.im/*
  93. // @match *://*.google.co.in/*
  94. // @match *://*.google.iq/*
  95. // @match *://*.google.is/*
  96. // @match *://*.google.it/*
  97. // @match *://*.google.je/*
  98. // @match *://*.google.com.jm/*
  99. // @match *://*.google.jo/*
  100. // @match *://*.google.jp/*
  101. // @match *://*.google.co.jp/*
  102. // @match *://*.google.co.ke/*
  103. // @match *://*.google.com.kh/*
  104. // @match *://*.google.ki/*
  105. // @match *://*.google.kg/*
  106. // @match *://*.google.co.kr/*
  107. // @match *://*.google.com.kw/*
  108. // @match *://*.google.kz/*
  109. // @match *://*.google.la/*
  110. // @match *://*.google.com.lb/*
  111. // @match *://*.google.li/*
  112. // @match *://*.google.lk/*
  113. // @match *://*.google.co.ls/*
  114. // @match *://*.google.lt/*
  115. // @match *://*.google.lu/*
  116. // @match *://*.google.lv/*
  117. // @match *://*.google.com.ly/*
  118. // @match *://*.google.co.ma/*
  119. // @match *://*.google.md/*
  120. // @match *://*.google.me/*
  121. // @match *://*.google.mg/*
  122. // @match *://*.google.mk/*
  123. // @match *://*.google.ml/*
  124. // @match *://*.google.com.mm/*
  125. // @match *://*.google.mn/*
  126. // @match *://*.google.ms/*
  127. // @match *://*.google.com.mt/*
  128. // @match *://*.google.mu/*
  129. // @match *://*.google.mv/*
  130. // @match *://*.google.mw/*
  131. // @match *://*.google.com.mx/*
  132. // @match *://*.google.com.my/*
  133. // @match *://*.google.co.mz/*
  134. // @match *://*.google.com.na/*
  135. // @match *://*.google.com.ng/*
  136. // @match *://*.google.com.ni/*
  137. // @match *://*.google.ne/*
  138. // @match *://*.google.nl/*
  139. // @match *://*.google.no/*
  140. // @match *://*.google.com.np/*
  141. // @match *://*.google.nr/*
  142. // @match *://*.google.nu/*
  143. // @match *://*.google.co.nz/*
  144. // @match *://*.google.com.om/*
  145. // @match *://*.google.com.pa/*
  146. // @match *://*.google.com.pe/*
  147. // @match *://*.google.com.pg/*
  148. // @match *://*.google.com.ph/*
  149. // @match *://*.google.com.pk/*
  150. // @match *://*.google.pl/*
  151. // @match *://*.google.pn/*
  152. // @match *://*.google.com.pr/*
  153. // @match *://*.google.ps/*
  154. // @match *://*.google.pt/*
  155. // @match *://*.google.com.py/*
  156. // @match *://*.google.com.qa/*
  157. // @match *://*.google.ro/*
  158. // @match *://*.google.ru/*
  159. // @match *://*.google.rw/*
  160. // @match *://*.google.com.sa/*
  161. // @match *://*.google.com.sb/*
  162. // @match *://*.google.sc/*
  163. // @match *://*.google.se/*
  164. // @match *://*.google.com.sg/*
  165. // @match *://*.google.sh/*
  166. // @match *://*.google.si/*
  167. // @match *://*.google.sk/*
  168. // @match *://*.google.com.sl/*
  169. // @match *://*.google.sn/*
  170. // @match *://*.google.so/*
  171. // @match *://*.google.sm/*
  172. // @match *://*.google.sr/*
  173. // @match *://*.google.st/*
  174. // @match *://*.google.com.sv/*
  175. // @match *://*.google.td/*
  176. // @match *://*.google.tg/*
  177. // @match *://*.google.co.th/*
  178. // @match *://*.google.com.tj/*
  179. // @match *://*.google.tl/*
  180. // @match *://*.google.tm/*
  181. // @match *://*.google.tn/*
  182. // @match *://*.google.to/*
  183. // @match *://*.google.com.tr/*
  184. // @match *://*.google.tt/*
  185. // @match *://*.google.com.tw/*
  186. // @match *://*.google.co.tz/*
  187. // @match *://*.google.com.ua/*
  188. // @match *://*.google.co.ug/*
  189. // @match *://*.google.co.uk/*
  190. // @match *://*.google.com.uy/*
  191. // @match *://*.google.co.uz/*
  192. // @match *://*.google.com.vc/*
  193. // @match *://*.google.co.ve/*
  194. // @match *://*.google.vg/*
  195. // @match *://*.google.co.vi/*
  196. // @match *://*.google.com.vn/*
  197. // @match *://*.google.vu/*
  198. // @match *://*.google.ws/*
  199. // @match *://*.google.rs/*
  200. // @match *://*.google.co.za/*
  201. // @match *://*.google.co.zm/*
  202. // @match *://*.google.co.zw/*
  203. // @match *://*.google.cat/*
  204. // @grant none
  205. // @inject-into content
  206. // @run-at document-start
  207. // @noframes
  208. // ==/UserScript==
  209. // https://www.google.com/supported_domains
  210.  
  211. (function () {
  212. "use strict";
  213.  
  214. if (window.top !== window.self) return; // @noframes
  215. if (location.pathname == "/url") return;
  216. const plang = navigator.language; // Preferred language // 首选语言
  217. const slang = "en-US"; // Second language // 第二语言
  218. const is_zh = ["ZH", "ZH-CN"].includes(plang.toUpperCase());
  219. const o_url = new URL(location);
  220. let url;
  221. // captcha
  222. if (location.pathname.startsWith("/sorry/index")) {
  223. const _continue = o_url.searchParams.get("continue");
  224. if (!_continue) return;
  225. url = new URL(_continue);
  226. } else {
  227. url = new URL(location);
  228. }
  229. let pfull = plang;
  230. let region = "AUTO"; // Current Region // 当前区域
  231. if (plang.length == 5 && plang[2] == "-") {
  232. region = plang.slice(-2).toUpperCase();
  233. url.searchParams.set("gl", region);
  234. } else {
  235. pfull = plang + "-" + region;
  236. url.searchParams.delete("gl");
  237. }
  238. url.searchParams.set("hl", plang);
  239. url.searchParams.delete("client");
  240. const _index = url.hostname.indexOf("google.");
  241. if (_index < 0) return;
  242. const current_domian = url.hostname.slice(_index);
  243. const default_domain = "google.com";
  244. if (current_domian === default_domain) {
  245. if (location.pathname.startsWith("/sorry/index")) return; // captcha
  246. } else {
  247. if (navigator.cookieEnabled) {
  248. url.hostname = location.hostname.replace(current_domian, default_domain);
  249. url.href = "https://www.google.com/ncr#ncr:" + encodeURIComponent(url);
  250. window.stop();
  251. location.replace(url);
  252. return;
  253. } else {
  254. if (is_zh) {
  255. alert(
  256. "[ACT.谷歌.DM.NCR]:\nCookie 已禁用,NCR 功能将不会生效。请检查浏览器设置。",
  257. );
  258. } else {
  259. alert(
  260. "[ACT.Google.DM.NCR]:\nCookies disabled, the NCR feature will not be active. Please check the browser settings.",
  261. );
  262. }
  263. }
  264. }
  265. if (o_url.hash.slice(0, 5) == "#ncr:") {
  266. location.hash = "";
  267. window.stop();
  268. location.replace(decodeURIComponent(o_url.hash.slice(5)));
  269. return;
  270. }
  271.  
  272. const r1 = region;
  273. const r2 = region == slang.toUpperCase().slice(-2) ? "AUTO" : slang.slice(-2);
  274. const l1 = plang;
  275. const l2 = plang.toUpperCase() == slang.toUpperCase() ? "AUTO" : slang;
  276. const langbar = document.createElement("div");
  277. const langbar_ = document.createElement("div");
  278. const langbar_r = document.createElement("div");
  279. const langbar_r_r1 = document.createElement("span");
  280. const langbar_r_r2 = document.createElement("span");
  281. const langbar_l = document.createElement("div");
  282. const langbar_l_l1 = document.createElement("span");
  283. const langbar_l_l2 = document.createElement("span");
  284. const langbar_s = document.createElement("div");
  285. const langbar_s_t = document.createElement("span");
  286. langbar.className = "act_langbar appbar mnr-c";
  287. langbar_.className = "card-section mnr-c";
  288. langbar_r.textContent = is_zh ? "区域:" : "REGION:";
  289. langbar_l.textContent = is_zh ? "语言:" : "LANGUAGE:";
  290. langbar_s.textContent = is_zh ? "区域&语言:" : "R&L:";
  291. langbar_r_r1.textContent = r1.toUpperCase();
  292. langbar_r_r2.textContent = r2.toUpperCase();
  293. langbar_l_l1.textContent = l1.toUpperCase();
  294. langbar_l_l2.textContent = l2.toUpperCase();
  295. langbar_r.append(langbar_r_r1, langbar_r_r2);
  296. langbar_l.append(langbar_l_l1, langbar_l_l2);
  297. langbar_s.append(langbar_s_t);
  298. langbar_.append(langbar_r, langbar_l, langbar_s);
  299. langbar.append(langbar_);
  300. let gl = r1,
  301. hl = plang,
  302. ss = 0;
  303. const ogl = o_url.searchParams.get("gl");
  304. const ohl = o_url.searchParams.get("hl");
  305. const safe_echo = (s) =>
  306. (s.match(/^[a-zA-Z]{2}(?:-[a-zA-Z]{2})?$/)?.[0] || "N/A").toUpperCase();
  307. switch (
  308. ogl?.toUpperCase() // Region
  309. ) {
  310. case r1.toUpperCase():
  311. langbar_r_r1.className = "act";
  312. gl = r2;
  313. break;
  314. case r2.toUpperCase():
  315. langbar_r_r2.className = "act";
  316. gl = r1;
  317. break;
  318. case undefined:
  319. r1 == "AUTO"
  320. ? ((langbar_r_r1.className = "act"), (gl = r2))
  321. : ((langbar_r_r2.className = "act"),
  322. (langbar_r_r2.textContent = "AUTO"),
  323. ss++);
  324. break;
  325. default:
  326. langbar_r_r2.className = "act";
  327. langbar_r_r2.textContent = safe_echo(ogl);
  328. ss++;
  329. }
  330. switch (
  331. ohl?.toUpperCase() // Language
  332. ) {
  333. case plang.toUpperCase():
  334. langbar_l_l1.className = "act";
  335. hl = l2;
  336. langbar_s_t.textContent = slang.toUpperCase();
  337. break;
  338. case slang.toUpperCase():
  339. langbar_l_l2.className = "act";
  340. hl = l1;
  341. langbar_s_t.textContent = pfull.toUpperCase();
  342. break;
  343. case undefined:
  344. langbar_l_l2.className = "act";
  345. langbar_l_l2.textContent = "AUTO";
  346. ss++;
  347. break;
  348. default:
  349. langbar_l_l2.className = "act";
  350. langbar_l_l2.textContent = safe_echo(ohl);
  351. ss++;
  352. }
  353. let sgl = gl,
  354. shl = hl;
  355. if ([r2, l2].includes("AUTO")) {
  356. ss > 1 &&
  357. ((sgl = r1), (shl = l1), (langbar_s_t.textContent = l1.toUpperCase()));
  358. ss < 2 && langbar_s.remove();
  359. } else {
  360. ss &&
  361. ((sgl = r2), (shl = l2), (langbar_s_t.textContent = l2.toUpperCase()));
  362. ss || hl.endsWith(gl) || langbar_s.remove();
  363. }
  364. url = new URL(location);
  365. langbar_r.addEventListener(
  366. "click",
  367. (event) => {
  368. gl == "AUTO"
  369. ? url.searchParams.delete("gl")
  370. : url.searchParams.set("gl", gl);
  371. location.replace(url);
  372. },
  373. true,
  374. );
  375. langbar_l.addEventListener(
  376. "click",
  377. (event) => {
  378. if (langbar_l_l2.textContent === "") return;
  379. hl == "AUTO"
  380. ? url.searchParams.delete("hl")
  381. : url.searchParams.set("hl", hl);
  382. location.replace(url);
  383. },
  384. true,
  385. );
  386. langbar_s.addEventListener(
  387. "click",
  388. (event) => {
  389. sgl == "AUTO"
  390. ? url.searchParams.delete("gl")
  391. : url.searchParams.set("gl", sgl);
  392. shl == "AUTO"
  393. ? url.searchParams.delete("hl")
  394. : url.searchParams.set("hl", shl);
  395. location.replace(url);
  396. },
  397. true,
  398. );
  399. const langbar_style = document.createElement("style");
  400. langbar_style.textContent = `
  401. .act_langbar {
  402. line-height: 2;
  403. margin-bottom: 6px;
  404. user-select: none;
  405. -webkit-user-select: none;
  406. }
  407. .act_langbar>div {
  408. white-space: nowrap;
  409. overflow-x: scroll !important;
  410. scrollbar-width: none;
  411. mask-image: linear-gradient(to left, transparent, red 25px);
  412. -webkit-mask-image: linear-gradient(to left, transparent, red 25px);
  413. }
  414. .act_langbar>div::-webkit-scrollbar { display: none; }
  415. .act_langbar>div>div {
  416. display: inline-block;
  417. padding: 0px 10px;
  418. margin-block: 3px;
  419. margin-inline: 0 15px;
  420. border: 1.5px solid;
  421. border-radius: 20px;
  422. cursor: pointer;
  423. opacity: 0.8;
  424. }
  425. .act_langbar>div>div:hover { opacity: 1; }
  426. .act_langbar span {
  427. margin-left: 10px;
  428. }
  429. .act_langbar span.act {
  430. padding: 1px 5px;
  431. border: 1px solid;
  432. border-radius: 20px;
  433. }
  434. `;
  435.  
  436. if (document.head) {
  437. document.head.append(langbar_style);
  438. } else {
  439. new MutationObserver((mutationList, observer) => {
  440. document.head &&
  441. (observer.disconnect(), document.head.append(langbar_style));
  442. }).observe(document, { subtree: true, childList: true });
  443. }
  444.  
  445. if (document.querySelector("#appbar")) {
  446. document.querySelector("#appbar")?.after(langbar);
  447. } else {
  448. new MutationObserver((mutationList, observer) => {
  449. if (document.querySelector("#appbar")) {
  450. observer.disconnect();
  451. document.querySelector("#appbar")?.after(langbar);
  452. }
  453. document.readyState == "complete" && observer.disconnect();
  454. }).observe(document, { subtree: true, childList: true });
  455. }
  456. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址