Disable Google Search Result URL Redirector

Disable Google URL redirector (i.e. user data tracking) on Google Search result, including Google Custom Search Engine (CSE) which is used by many websites, and in Google Groups.

当前为 2019-05-21 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Disable Google Search Result URL Redirector
  3. // @namespace DisableGoogleSearchResultURLRedirector
  4. // @version 1.1.9
  5. // @license GNU AGPLv3
  6. // @author jcunews
  7. // @website https://greasyfork.org/en/users/85671-jcunews
  8. // @description Disable Google URL redirector (i.e. user data tracking) on Google Search result, including Google Custom Search Engine (CSE) which is used by many websites, and in Google Groups.
  9. // @include *://*/*
  10. // @grant unsafeWindow
  11. // @run-at document-start
  12. // ==/UserScript==
  13.  
  14. (function(createElement_, appendChild_, insertBefore_) {
  15.  
  16. //===== CONFIGURATION BEGIN =====
  17.  
  18. var disableGoogleAdSense = true;
  19.  
  20. //===== CONFIGURATION END =====
  21.  
  22. function rwt_() { return true }
  23.  
  24. function checkElement(ele, m, obj, fn) {
  25. if (ele.tagName === "SCRIPT") {
  26. if (disableGoogleAdSense && (/:\/\/cse\.google\.com\/adsense\/search\/(async-)?ads\.js/).test(ele.src)) {
  27. return false;
  28. } else if (m = ele.src.match(/:\/\/www.googleapis.com\/customsearch\/.*callback=([^?]+)/)) {
  29. obj = unsafeWindow;
  30. m[1].split(".").forEach(function(k, i, a) {
  31. if (i < (a.length - 1)) {
  32. obj = obj[k];
  33. } else {
  34. fn = obj[k];
  35. obj[k] = function(data) {
  36. data.results.forEach(function(res) {
  37. delete res.clicktrackUrl;
  38. });
  39. return fn.apply(this, arguments);
  40. };
  41. }
  42. });
  43. }
  44. }
  45. return true;
  46. }
  47.  
  48. if ((/(www|groups)\.google\.[a-z]+(\.[a-z]+)?/).test(location.hostname)) {
  49. //Google site
  50. addEventListener("mousedown", function() {
  51. if (unsafeWindow.rwt && (unsafeWindow.rwt !== rwt_)) unsafeWindow.rwt = rwt_;
  52. }, true);
  53. //Google image search site
  54. let setAttribute = HTMLAnchorElement.prototype.setAttribute;
  55. HTMLAnchorElement.prototype.setAttribute = function(name, value) {
  56. if ((name === "href") && !this.dataset_) {
  57. let a = this, href = value;
  58. this.dataset_ = this.dataset;
  59. Object.defineProperty(this, "dataset", {
  60. value: new Proxy(this.dataset_, {
  61. set: function(tgt, prop, val, recv) {
  62. if ((prop === "cthref") && (/^\/url\?/).test(val)) {
  63. a.href = href;
  64. a.rel = "noreferer";
  65. } else a.dataset_[prop] = val;
  66. return true;
  67. }
  68. })
  69. });
  70. }
  71. return setAttribute.apply(this, arguments);
  72. };
  73. //Google Groups and probably others too
  74. let desc = Object.getOwnPropertyDescriptor(HTMLAnchorElement.prototype, "href");
  75. let setHref = desc.set;
  76. desc.set = function(value) {
  77. if ((/\/url.*[?&]q=(ht|f)tp/).test(value)) {
  78. this.rel = "noreferer";
  79. return this.href;
  80. } else return setHref.apply(this, arguments);
  81. };
  82. Object.defineProperty(HTMLAnchorElement.prototype, "href", desc);
  83. } else {
  84. //other sites
  85. appendChild_ = Node.prototype.appendChild;
  86. Node.prototype.appendChild = function(ele) {
  87. if (checkElement(ele)) {
  88. return appendChild_.apply(this, arguments);
  89. } else return ele;
  90. };
  91. insertBefore_ = Node.prototype.insertBefore;
  92. Node.prototype.insertBefore = function(ele) {
  93. if (checkElement(ele)) {
  94. return insertBefore_.apply(this, arguments);
  95. } else return ele;
  96. };
  97. }
  98.  
  99. })();