Duanmao HTTPS

使断锚网页版支持 HTTPS

  1. // ==UserScript==
  2. // @name Duanmao HTTPS
  3. // @namespace CCCC_David
  4. // @version 0.4.0
  5. // @description 使断锚网页版支持 HTTPS
  6. // @author CCCC_David
  7. // @match https://duanmao.top/*
  8. // @run-at document-start
  9. // @grant none
  10. // @require https://unpkg.com/ajax-hook/dist/ajaxhook.min.js
  11. // ==/UserScript==
  12.  
  13. (() => {
  14. 'use strict';
  15.  
  16. const fixURL = (url) => url === undefined ? undefined : url.replace(/^https?:\/\/cdn1\.duanmao\.top\//i, 'https://duanmao.top/')
  17. .replace(/^http:\/\//i, 'https://');
  18. ah.proxy({
  19. onRequest: (config, handler) => {
  20. config.url = fixURL(config.url);
  21. handler.next(config);
  22. },
  23. onError: (err, handler) => {
  24. handler.next(err);
  25. },
  26. onResponse: (response, handler) => {
  27. handler.next(response);
  28. },
  29. });
  30.  
  31. const pathname = window.location.pathname;
  32. const isForumPage = pathname === '/forum';
  33.  
  34. const addMetaTags = () => {
  35. const metaReferrer = document.createElement('meta');
  36. metaReferrer.name = 'referrer';
  37. metaReferrer.content = 'same-origin';
  38. document.head.appendChild(metaReferrer);
  39. const metaCSP = document.createElement('meta');
  40. metaCSP.httpEquiv = 'Content-Security-Policy';
  41. metaCSP.content = "base-uri 'self'; script-src 'self'; object-src 'none'; upgrade-insecure-requests";
  42. document.head.appendChild(metaCSP);
  43. };
  44.  
  45. const updateElementURL = (el) => {
  46. const tagName = el.nodeName.toLowerCase();
  47. // There are many HTML tag attributes which can include URLs
  48. // (see https://stackoverflow.com/questions/2725156/complete-list-of-html-tag-attributes-which-have-a-url-value),
  49. // but here we just deal with the most common two cases:
  50. // - <a href="..."></a>
  51. // - <img src="..." />
  52. if (tagName === 'a') {
  53. el.href = fixURL(el.href);
  54. } else if (tagName === 'img') {
  55. el.src = fixURL(el.src);
  56. }
  57. };
  58.  
  59. const settingsHasHTTPS = () => {
  60. try {
  61. return JSON.parse(window.localStorage.getItem('cdn')).data === 0;
  62. } catch {
  63. return false;
  64. }
  65. };
  66.  
  67. const observer = new MutationObserver((mutationsList) => {
  68. for (const mutation of mutationsList) {
  69. if (mutation.type === 'childList') {
  70. for (const el of mutation.addedNodes) {
  71. if (el.nodeName.toLowerCase() === 'head') {
  72. addMetaTags();
  73. }
  74. updateElementURL(el);
  75. }
  76. }
  77. }
  78. });
  79.  
  80. observer.observe(document.documentElement, {
  81. subtree: true,
  82. childList: true,
  83. });
  84.  
  85. if (document.head) {
  86. addMetaTags();
  87. }
  88.  
  89. for (const tagName of ['a', 'img']) {
  90. for (const el of document.getElementsByTagName(tagName)) {
  91. updateElementURL(el);
  92. }
  93. }
  94.  
  95. if (isForumPage) {
  96. window.addEventListener('DOMContentLoaded', () => {
  97. // If the inline script was blocked, we execute it again.
  98. if (!document.querySelector('meta[name="viewport"]')) {
  99. window.coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') || CSS.supports('top: constant(a)'));
  100. const metaViewport = document.createElement('meta');
  101. metaViewport.name = 'viewport';
  102. metaViewport.content = 'width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' + (window.coverSupport ? ', viewport-fit=cover' : '');
  103. document.head.appendChild(metaViewport);
  104. }
  105.  
  106. if (!settingsHasHTTPS()) {
  107. // If the "/renew" request happened before our Ajax hook, it might be blocked due to Mixed Content error.
  108. // Here we send it again.
  109. try {
  110. for (const func of getApp().$options.onLaunch) {
  111. if (func.toString().includes('renew') && func.length === 0) {
  112. func();
  113. }
  114. }
  115. } catch (e) {
  116. console.error(e);
  117. }
  118. }
  119. });
  120. }
  121.  
  122. if (pathname === '/fourm') { // cSpell:disable-line
  123. window.location.replace('/forum');
  124. }
  125.  
  126. console.log('Duanmao HTTPS script is loaded');
  127. })();