4chan bypass derefer link interstitial

Bypasses the derefer link interstitial for external links on 4chan

  1. // ==UserScript==
  2. // @name 4chan bypass derefer link interstitial
  3. // @namespace b3vwq7gg90yplbelsnvz
  4. // @match https://boards.4chan.org/*
  5. // @match https://boards.4channel.org/*
  6. // @match https://sys.4chan.org/derefer?*
  7. // @match https://sys.4channel.org/derefer?*
  8. // @grant none
  9. // @version 1.0.1
  10. // @description Bypasses the derefer link interstitial for external links on 4chan
  11. // @run-at document-start
  12. // @insert-into content
  13. // @license MIT
  14. // ==/UserScript==
  15.  
  16. (function () {
  17. "use strict";
  18.  
  19. if (location.hostname.startsWith("sys.4chan")) {
  20. // Derefer page (somehow), redirect immediately
  21. const real = new URL(new URLSearchParams(location.search).get("url"));
  22.  
  23. if (real && (real.protocol === "https:" || real.protocol === "http:")) {
  24. const link = document.createElement("a");
  25. link.rel = "noopener";
  26. link.referrerPolicy = "no-referrer";
  27. // Hack fix: 4chan fucks up by double-encoding ampersands
  28. link.href = String(real).replaceAll("&", "&");
  29. link.click();
  30. }
  31. } else {
  32. // Board page, fix linkified links
  33. const dereferLink = "//" + location.host.replace("boards.4chan", "sys.4chan") + "/derefer?url=";
  34. const derefSelector = `a.linkified[href^="${dereferLink}"]`;
  35.  
  36. document.addEventListener("4chanParsingDone", (ev) => {
  37. const tid = ev.detail?.threadId;
  38. let context;
  39.  
  40. if (tid) {
  41. context = document.getElementById(`t${tid}`);
  42. }
  43.  
  44. // If we don't find the thread for some reason,
  45. // just scan the entire page instead idk
  46. if (!context) {
  47. context = document.body;
  48. }
  49.  
  50.  
  51. for (const link of context.querySelectorAll(derefSelector)) {
  52. let real;
  53.  
  54. try {
  55. // Throws if invalid URL.
  56. // Use textContent instead of the url parameter
  57. // because that might have double encoded ampersands
  58. real = new URL(link.textContent);
  59. } catch {
  60. continue;
  61. }
  62.  
  63. if (real.protocol === "https:" || real.protocol === "http:") {
  64. link.relList.add("noopener");
  65. link.referrerPolicy = "no-referrer";
  66. link.href = real;
  67. }
  68. }
  69. });
  70. }
  71. })();