External Link Auto Redirect(Direct Link)

redirect to the real URL directly when clicking on a link that contains a redirect URL

当前为 2024-03-11 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name External Link Auto Redirect(Direct Link)
  3. // @name:zh-CN 外链自动重定向(默认直链)
  4. // @namespace http://tampermonkey.net/
  5. // @version 1.1
  6. // @description redirect to the real URL directly when clicking on a link that contains a redirect URL
  7. // @description:zh-CN 点击包含重定向 URL 的链接时,直接跳转到到真实的 URL
  8. // @author uiliugang
  9. // @run-at document-start
  10. // @match *://*/*
  11. // @license MIT
  12. // ==/UserScript==
  13.  
  14. (function() {
  15. 'use strict';
  16.  
  17. const redirectRegex = /^https?:\/\/.*\?.*https?/;
  18. const videoExtensions = ['.mp4', '.m3u8', '.avi', '.mov', '.wmv', '.mkv', '.flv', '.webm', '.mpeg', '.mpg', '.mp2v', '.m4v', '.svi', '.asx', '.wmv', '.wmx', '.m4p', '.m4b', '.mxf', '.roq', '.nsv', '.flv', '.mpe?g', '.mp3v', '.m1v', '.m2v', '.vob', '.ifo', '.dat', '.divx', '.cpk', '.dirac', '.drc', '.mj2', '.mjv', '.mod', '.tod', '.rec', '.uvh', '.uvu', '.qt', '.rm', '.ram', '.rpm', '.smil', '.ice', '.gifv', '.nsv', '.3ivx', '.3gpp', '.f4v', '.f4p', '.f4a', '.f4b', '.mxf', '.roq', '.nsv', '.flv', '.m4v', '.avi', '.dat', '.divx', '.cpk', '.dirac', '.drc', '.mj2', '.mjp2', '.mjv', '.mod', '.tod', '.rec', 'uvh', 'uvu', 'qt', 'mov', 'movie', 'rm', 'ra', 'ram', 'rpm', 'smil', 'ice', 'mpe?g', 'mp2v', 'mp3v', 'm4v', 'svi', '.asx', 'wmv', 'wmx', 'wm', 'asf', 'amv', 'mpv', 'm1v', 'm2v', 'vob', '.ifo'];
  19.  
  20. function processUrl(redirectURL) {
  21. const matches = redirectURL.match(redirectRegex);
  22. console.log(`Matches: ${matches}`);
  23. if (matches) {
  24. let index = redirectURL.substring(4).indexOf("http")+3;
  25. let realUrl = decodeURIComponent(redirectURL.substring(index + 1));
  26. console.log(`Decoded URL: ${realUrl}`);
  27. if (isValidUrlAndNotVideo(realUrl)) {
  28. return realUrl;
  29. }
  30. }
  31. return null;
  32. }
  33.  
  34. function isValidUrlAndNotVideo(string) {
  35. try {
  36. const url = new URL(string);
  37. const pathname = url.pathname;
  38. for (const ext of videoExtensions) {
  39. if (pathname.endsWith(ext)) {
  40. return false;
  41. }
  42. }
  43. return true;
  44. } catch (e) {
  45. return false;
  46. }
  47. }
  48.  
  49. function handleClick(e) {
  50. let url = '';
  51. let processedUrl = '';
  52. // 检查点击的元素是否具有 href 属性
  53. if (e.target && e.target.href) {
  54. url = e.target.href;
  55. processedUrl = processUrl(url);
  56. if (processedUrl) {
  57. e.preventDefault();
  58. window.open(processedUrl, '_blank');
  59. }
  60. }
  61.  
  62. // 如果点击的元素没有 href 属性,则检查其父元素
  63. else if (e.target.parentElement && e.target.parentElement.href) {
  64. url = e.target.parentElement.href;
  65. processedUrl = processUrl(url);
  66. if (processedUrl) {
  67. e.preventDefault();
  68. window.open(processedUrl, '_blank');
  69. }
  70. }
  71. // 如果点击的元素或其父元素都没有 href 属性,则检查其祖先元素
  72. else if (e.target.parentElement && e.target.parentElement.parentElement && e.target.parentElement.parentElement.href) {
  73. url = e.target.parentElement.parentElement.href;
  74. processedUrl = processUrl(url);
  75. if (processedUrl) {
  76. e.preventDefault();
  77. window.open(processedUrl, '_blank');
  78. }
  79. }
  80. console.log(`Original URL: ${url}`);
  81. console.log(`Processed URL: ${processedUrl}`);
  82. }
  83.  
  84. document.addEventListener('click', handleClick);
  85.  
  86. let processedUrl = processUrl(window.location.href);
  87. if (processedUrl) {
  88. window.location.replace(processedUrl);
  89. }
  90. })();