请选择 进入手机版 | 继续访问电脑版

北海实用推荐

搜索

联系客服

查看: 806|回复: 0

[Tampermonkey脚本JS] Google:绕过搜索结果网页链接重定向

[复制链接]

141

主题

147

帖子

654

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
654
发表于 2017-12-9 18:57:57 | 显示全部楼层 |阅读模式
  1. // ==UserScript==
  2. // @namespace   VA_i
  3. // @version     8.0.0.20171116
  4. // @grant       GM.getValue
  5. // @grant       GM.setValue
  6. // @grant       GM_getValue
  7. // @grant       GM_setValue
  8. // @grant       unsafeWindow
  9. // @include     /^https?://(?:www|encrypted|ipv[46])\.google\.[^/]+/(?:$|[#?]|search|webhp|imgres)/
  10. // @match       https://news.google.com/*
  11. // @match       https://cse.google.com/cse/*
  12. // @run-at      document-start
  13. // @name        Google: Bypass Result Page Redirect
  14. // @name:zh-CN  Google:绕过搜索结果网页链接重定向
  15. // @name:zh-TW  Google:繞過搜尋結果網頁鏈接重定向
  16. // @description Avoid Google redirect for search result pages.
  17. // @description:zh-CN 令 Google 直接链接至搜索结果网页,无须重定向。
  18. // @description:zh-TW 令 Google 直接鏈接至搜尋結果網頁,無須重定向。
  19. // ==/UserScript==

  20. var M = (typeof GM !== 'undefined') ? GM : {
  21.   getValue: function (name, alt) {
  22.     var value = GM_getValue(name, alt);
  23.     return { then: function (callback) { callback(value); } };
  24.   },
  25.   setValue: function (name, value) {
  26.     GM_setValue(name, value);
  27.     return { then: function (callback) { callback(); } };
  28.   }
  29. };

  30. function getOption() {
  31.   var opt_noopen = false;
  32.   // For example: open https://ipv4.google.com/#x-option:open-inplace
  33.   switch (location.hash) {
  34.     // Open links in the current tab.
  35.     case '#x-option:open-inplace': opt_noopen = true; break;
  36.     // Do not ...
  37.     case '#x-option:no-open-inplace': opt_noopen = false; break;
  38.     default: return M.getValue('opt_noopen', opt_noopen);
  39.   }
  40.   M.setValue('opt_noopen', opt_noopen);
  41.   return { then: function (callback) { callback(opt_noopen); } };
  42. }

  43. function unsafeEval(func, opt) {
  44.   let body = 'return (' + func + ').apply(this, arguments)';
  45.   unsafeWindow.Function(body).call(unsafeWindow, opt);
  46. }

  47. getOption().then(function run(opt_noopen) {
  48. unsafeEval(function (opt_noopen) {

  49. var debug = false;
  50. var count = 0;

  51. var options = {opt_noopen: opt_noopen};
  52. debug && console.log('Options:', options);

  53. // web pages: url?url=
  54. // custom search engine: url?q=
  55. // malware: interstitial?url=
  56. var re = /\burl\?.*?\b(?:url|q)=(https?\b[^&#]+)/i;
  57. var restore = function (link, url) {
  58.   var oldUrl = link.getAttribute('href') || '';
  59.   var newUrl = url || oldUrl;
  60.   var matches = newUrl.match(re);
  61.   if (matches) {
  62.     debug && console.log('restoring', link._x_id, newUrl);
  63.     link.setAttribute('href', decodeURIComponent(matches[1]));
  64.     enhanceLink(link);
  65.   } else if (url != null) {
  66.     link.setAttribute('href', newUrl);
  67.   }
  68. };

  69. var purifyLink = function (a) {
  70.   if (/\brwt\(/.test(a.getAttribute('onmousedown'))) {
  71.     a.removeAttribute('onmousedown');
  72.   }
  73.   if (a.parentElement &&
  74.       /\bclick\b/.test(a.parentElement.getAttribute('jsaction') || '')) {
  75.     a.addEventListener('click', function (e) {
  76.       e.stopImmediatePropagation();
  77.       e.stopPropagation();
  78.     }, true);
  79.   }
  80. };

  81. var enhanceLink = function (a) {
  82.   purifyLink(a);
  83.   a.setAttribute('rel', 'noreferrer');
  84.   a.setAttribute('referrerpolicy', 'no-referrer');
  85.   if (options.opt_noopen) {
  86.     a.setAttribute('target', '_self');
  87.     a.addEventListener('click', function (event) {
  88.       event.stopImmediatePropagation();
  89.       event.stopPropagation();
  90.     }, true);
  91.   }
  92. };

  93. var fakeLink = document.createElement('a');
  94. var normalizeUrl = function (url) {
  95.   fakeLink.href = url;
  96.   return fakeLink.href;
  97. };

  98. var setter = function (v) {
  99.   v = String(v);  // in case an object is passed by clever Google
  100.   debug && console.log('State:', document.readyState);
  101.   debug && console.log('set', this._x_id, this.getAttribute('href'), v);
  102.   restore(this, v);
  103. };
  104. var getter = function () {
  105.   debug && console.log('get', this._x_id, this.getAttribute('href'));
  106.   return normalizeUrl(this.getAttribute('href'));
  107. };
  108. var blocker = function (event) {
  109.   event.stopPropagation();
  110.   restore(this);
  111.   debug && console.log('block', this._x_id, this.getAttribute('href'));
  112. };

  113. var handler = function (a) {
  114.   if (a._x_id) {
  115.     restore(a);
  116.     return;
  117.   }
  118.   a._x_id = ++count;
  119.   debug && a.setAttribute('x-id', a._x_id);
  120.   if (Object.defineProperty) {
  121.     debug && console.log('define property', a._x_id);
  122.     Object.defineProperty(a, 'href', {get: getter, set: setter});
  123.   } else if (a.__defineSetter__) {
  124.     debug && console.log('define getter', a._x_id);
  125.     a.__defineSetter__('href', setter);
  126.     a.__defineGetter__('href', getter);
  127.   } else {
  128.     debug && console.log('define listener', a._x_id);
  129.     a.onmouseenter = a.onmousemove = a.onmouseup = a.onmousedown =
  130.       a.ondbclick = a.onclick = a.oncontextmenu = blocker;
  131.   }
  132.   if (/^_(?:blank|self)$/.test(a.getAttribute('target')) ||
  133.       /\brwt\(/.test(a.getAttribute('onmousedown')) ||
  134.       /\bmouse/.test(a.getAttribute('jsaction')) ||
  135.       /\bclick\b/.test(a.parentElement.getAttribute('jsaction'))) {
  136.     enhanceLink(a);
  137.   }
  138.   restore(a);
  139. };

  140. var checkNewNodes = function (mutations) {
  141.   debug && console.log('State:', document.readyState);
  142.   if (mutations.target) {
  143.     checkAttribute(mutations);
  144.   } else {
  145.     mutations.forEach && mutations.forEach(checkAttribute);
  146.   }
  147. };
  148. var checkAttribute = function (mutation) {
  149.   var target = mutation.target;
  150.   if (target && target.nodeName.toUpperCase() === 'A') {
  151.     if ((mutation.attributeName || mutation.attrName) === 'href') {
  152.       debug && console.log('restore attribute', target._x_id, target.getAttribute('href'));
  153.     }
  154.     handler(target);
  155.   } else if (target instanceof Element) {
  156.     [].slice.call(target.querySelectorAll('a')).forEach(handler);
  157.   }
  158. };

  159. var MutationObserver = window.MutationObserver || window.WebKitMutationObserver;

  160. if (MutationObserver) {
  161.   debug && console.log('MutationObserver: true');
  162.   new MutationObserver(checkNewNodes).observe(document.documentElement, {
  163.     childList: true,
  164.     attributes: true,
  165.     attributeFilter: ['href'],
  166.     subtree: true
  167.   });
  168. } else {
  169.   debug && console.log('MutationEvent: true');
  170.   document.addEventListener('DOMAttrModified', checkAttribute, false);
  171.   document.addEventListener('DOMNodeInserted', checkNewNodes, false);
  172. }

  173. }, opt_noopen);
  174. });
复制代码

请关注公众号:“北海实用推荐”,期待我们下次更新。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|北海实用推荐 ( 桂ICP备15001999号-2  

GMT+8, 2018-10-19 09:36 , Processed in 1.056172 second(s), 10 queries , Xcache On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表