Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The userscript won't work on firefox with greasemonkey. #8

Open
eebssk1 opened this issue Jul 8, 2023 · 11 comments
Open

The userscript won't work on firefox with greasemonkey. #8

eebssk1 opened this issue Jul 8, 2023 · 11 comments

Comments

@eebssk1
Copy link

eebssk1 commented Jul 8, 2023

Due to how firefox handle document-start,the test facility of the script won't work.
See greasemonkey/greasemonkey#2515

Here my own modified one that currently works.

// ==UserScript==
// @name Jsdelivr Auto Fallback
// @namespace https://github.com/PipecraftNet/jsdelivr-auto-fallback
// @version 0.2.2
// @author PipecraftNet&DreamOfIce
// @description 修复 cdn.jsdelivr.net 无法访问的问题
// @homepage https://github.com/PipecraftNet/jsdelivr-auto-fallback
// @supportURL https://github.com/PipecraftNet/jsdelivr-auto-fallback/issues
// @license MIT
// @match *://*/*
// @run-at document-start
// @grant GM_setValue
// @grant GM_getValue
// ==/UserScript==

function act() {
  'use strict';
  let fastNode;
  let failed;
  let isRunning;
  const DEST_LIST = [
    'cdn.jsdelivr.net',
    'unpkg.com',
    'testingcf.jsdelivr.net',
    'test1.jsdelivr.net',
    'fastly.jsdelivr.net',
    'gcore.jsdelivr.net',
  ];
  const PREFIX = '//';
  const SOURCE = DEST_LIST[0];
  const starTime = Date.now();
  const TIMEOUT = 800;
  const STORE_KEY = 'jsdelivr-auto-fallback';
  const TEST_PATH = '/empty@0.10.1/object.js?';
  const shouldReplace = (text) => text && text.includes(PREFIX + SOURCE);
  const replace = (text) => text.replace(PREFIX + SOURCE, PREFIX + fastNode);
  const setTimeout = window.setTimeout;
  const $ = document.querySelectorAll.bind(document);

  const replaceElementSrc = () => {
    let element;
    let value;
    for (element of $('link[rel="stylesheet"]')) {
      value = element.href;
      if (shouldReplace(value) && !value.includes(TEST_PATH)) {
        element.href = replace(value);
      }
    }

    for (element of $('script')) {
      value = element.src;
      if (shouldReplace(value)) {
        const newNode = document.createElement('script');
        newNode.src = replace(value);
        element.defer = true;
        element.src = '';
        element.before(newNode);
        element.remove();
      }
    }

    for (element of $('img')) {
      value = element.src;
      if (shouldReplace(value)) {
        // Used to cancel loading. Without this line it will remain pending status.
        element.src = '';
        element.src = replace(value);
      }
    }

    // All elements that have a style attribute
    for (element of $('*[style]')) {
      value = element.getAttribute('style');
      if (shouldReplace(value)) {
        element.setAttribute('style', replace(value));
      }
    }

    for (element of $('style')) {
      value = element.innerHTML;
      if (shouldReplace(value)) {
        element.innerHTML = replace(value);
      }
    }
  };

  const tryReplace = () => {
    if (!isRunning && failed && fastNode) {
      console.warn(SOURCE + ' is not available. Use ' + fastNode);
      isRunning = true;
      setTimeout(replaceElementSrc, 0);
      // Some need to wait for a while
      setTimeout(replaceElementSrc, 20);
      // Replace dynamically added elements
      setInterval(replaceElementSrc, 500);
    }else{
      console.log("Use original target.");
    }
  };

  const checkAvailable = (url, callback) => {
    let timeoutId;
    const newNode = document.createElement('link');
    const handleResult = (isSuccess) => {
      if (!timeoutId) {
        return;
      }

      clearTimeout(timeoutId);
      timeoutId = 0;
      // Used to cancel loading. Without this line it will remain pending status.
      if (!isSuccess) newNode.href = 'data:text/plain;base64,';
      newNode.remove();
      callback(isSuccess);
      console.log(url + " is Ok..");
    };

    timeoutId = setTimeout(handleResult, TIMEOUT);

    newNode.addEventListener('error', () => handleResult(false));
    newNode.addEventListener('load', () => handleResult(true));
    newNode.rel = 'prefetch';
    newNode.text = 'text/javascript';
    newNode.href = url + TEST_PATH + starTime;
    console.log("Testing .. " + url);
    if(document.head !== null) {
    document.head.insertAdjacentElement('afterbegin', newNode);
    }else{
      console.log("DOM not fully ready!");
    }
  };

  const cached = (() => {
    try {
      // eslint-disable-next-line new-cap
      return Object.assign({}, GM_getValue(STORE_KEY));
    } catch {
      return {};
    }
  })();

  const main = () => {
    cached.time = starTime;
    cached.failed = false;
    cached.fastNode = null;

    for (const url of DEST_LIST) {
      checkAvailable('https://' + url, (isAvailable) => {
        // console.log(url, Date.now() - starTime, Boolean(isAvailable));
        if (!isAvailable && url === SOURCE) {
          failed = true;
          cached.failed = true;
        }

        if (isAvailable && !fastNode) {
          fastNode = url;
        }

        if (isAvailable && !cached.fastNode) {
          cached.fastNode = url;
        }

        tryReplace();
      });
    }

    setTimeout(() => {
      // If all domains are timeout
      if (failed && !fastNode) {
        fastNode = DEST_LIST[1];
        tryReplace();
      }

      // eslint-disable-next-line new-cap
      GM_setValue(STORE_KEY, cached);
    }, TIMEOUT + 200);
  };

  if (
    cached.time &&
    starTime - cached.time < 60 * 60 * 1000 &&
    cached.failed &&
    cached.fastNode
  ) {
    failed = true;
    fastNode = cached.fastNode;
    tryReplace();
    setTimeout(main, 1000);
  } else {
    main();
  }
}
const observer = new MutationObserver(() => {
  if(document.head !== null) {
    observer.disconnect();
    act();
    console.log("Head is OK now");
  }
});
const observerOptions = {
  childList: true,
  subtree: true,
};
observer.observe(document,observerOptions);
@PipecraftNet
Copy link
Owner

感谢提供信息,已修改代码,使用 MutationObserver 检查 head 是否存在。

上面代码中 TEST_PATH 修改的部分因为没有时间验证,本次版本先不打算修改。

如有其他问题欢迎反馈。

@DreamOfIce
还请麻烦你在 greasyfork 更新一下脚本。
或者在 greasyfork 中添加一下我 (https://greasyfork.org/zh-CN/users/1030884-pipecraft) 为脚本作者。

谢谢。

@DreamOfIce
Copy link
Contributor

感谢提供信息,已修改代码,使用 MutationObserver 检查 head 是否存在。

上面代码中 TEST_PATH 修改的部分因为没有时间验证,本次版本先不打算修改。

如有其他问题欢迎反馈。

@DreamOfIce 还请麻烦你在 greasyfork 更新一下脚本。 或者在 greasyfork 中添加一下我 (https://greasyfork.org/zh-CN/users/1030884-pipecraft) 为脚本作者。

谢谢。

GreasyFork邀请发了

@PipecraftNet
Copy link
Owner

GreasyFork邀请发了

谢谢,已更新脚本代码。

@eebssk1
Copy link
Author

eebssk1 commented Jul 15, 2023

@PipecraftNet
Your url test method may not work under firefox

GET
https://cdn.zenless.top/gh/PipecraftNet/jsdelivr-auto-fallback@main/empty.css?1689433198847

样式表单 data:text/plain;base64, 未加载,因为它的 MIME 类型 "text/plain" 不是 "text/css"。 [uupdump.net](https://uupdump.net/)
来自“https://cdn.zenless.top/gh/PipecraftNet/jsdelivr-auto-fallback@main/empty.css?1689433198847”的资源已被阻止,因为 MIME 类型(“text/plain”)不匹配(X-Content-Type-Options: nosniff)。
[uupdump.net](https://uupdump.net/)
样式表单 data:text/plain;base64, 未加载,因为它的 MIME 类型 "text/plain" 不是 "text/css"。

I haven't investigate if it works or not yet. Howver I think you should consider this broken on firefox since unlike chrome, the little cuty fox won't give you a chance on this.

@DreamOfIce
Copy link
Contributor

DreamOfIce commented Jul 15, 2023

https://cdn.zenless.top/gh/PipecraftNet/jsdelivr-auto-fallback@main/empty.css?1689433198847

It seems that it's my mistake, this URL returns: Invalid URL. The URL structure is /gh/user/repo@version/file.js instead of null css.
I will check the reason later.

@DreamOfIce
Copy link
Contributor

@PipecraftNet

Your url test method may not work under firefox


GET

https://cdn.zenless.top/gh/PipecraftNet/jsdelivr-auto-fallback@main/empty.css?1689433198847



样式表单 data:text/plain;base64, 未加载,因为它的 MIME 类型 "text/plain" 不是 "text/css"。 [uupdump.net](https://uupdump.net/)

来自“https://cdn.zenless.top/gh/PipecraftNet/jsdelivr-auto-fallback@main/empty.css?1689433198847”的资源已被阻止,因为 MIME 类型(“text/plain”)不匹配(X-Content-Type-Options: nosniff)。

[uupdump.net](https://uupdump.net/)

样式表单 data:text/plain;base64, 未加载,因为它的 MIME 类型 "text/plain" 不是 "text/css"。

I haven't investigate if it works or not yet. Howver I think you should consider this broken on firefox since unlike chrome, the little cuty fox won't give you a chance on this.

The problem should have been solved, can you try again?

Here are the reasons for the error:
In order to optimize the user experience, I introduced CacheFly CDN a few weeks ago and after a brief test used it as the main CDN in the direction of China Telecom.
At that time, I did not test URIs with special characters, so I did not find that CacheFly automatically encodes URIs, and jsdelivr could not recognize the @ that was converted to %40.

I've used njs to decode all request URIs, if there are any other issues, feel free to ask!

@eebssk1
Copy link
Author

eebssk1 commented Jul 16, 2023

Now firefox is giving you headaches.

Content-Security-Policy:页面设置阻止读取位于 https://cdn.jsdelivr.net/gh/PipecraftNet/jsdelivr-auto-fallback@main/empty.css?1689519508980 的一项资源("style-src")。 [8:122:18](https://github.com/PipecraftNet/jsdelivr-auto-fallback/issues/8?notification_referrer_id=NT_kwDOAPveaLM3MDAyNTUxMTk0OjE2NTA2NDcy#issuecomment-1636996229%20line%201%20%3E%20injectedScript) Content-Security-Policy:页面设置阻止读取位于 https://unpkg.com/gh/PipecraftNet/jsdelivr-auto-fallback@main/empty.css?1689519508980 的一项资源("style-src")。 [8:122:18](https://github.com/PipecraftNet/jsdelivr-auto-fallback/issues/8?notification_referrer_id=NT_kwDOAPveaLM3MDAyNTUxMTk0OjE2NTA2NDcy#issuecomment-1636996229%20line%201%20%3E%20injectedScript) Content-Security-Policy:页面设置阻止读取位于 https://fastly.jsdelivr.net/gh/PipecraftNet/jsdelivr-auto-fallback@main/empty.css?1689519508980 的一项资源("style-src")。 [8:122:18](https://github.com/PipecraftNet/jsdelivr-auto-fallback/issues/8?notification_referrer_id=NT_kwDOAPveaLM3MDAyNTUxMTk0OjE2NTA2NDcy#issuecomment-1636996229%20line%201%20%3E%20injectedScript) Content-Security-Policy:页面设置阻止读取位于 https://gcore.jsdelivr.net/gh/PipecraftNet/jsdelivr-auto-fallback@main/empty.css?1689519508980 的一项资源("style-src")。 [8:122:18](https://github.com/PipecraftNet/jsdelivr-auto-fallback/issues/8?notification_referrer_id=NT_kwDOAPveaLM3MDAyNTUxMTk0OjE2NTA2NDcy#issuecomment-1636996229%20line%201%20%3E%20injectedScript) Content-Security-Policy:页面设置阻止读取位于 https://cdn.zenless.top/gh/PipecraftNet/jsdelivr-auto-fallback@main/empty.css?1689519508980 的一项资源("style-src")。 [8:122:18](https://github.com/PipecraftNet/jsdelivr-auto-fallback/issues/8?notification_referrer_id=NT_kwDOAPveaLM3MDAyNTUxMTk0OjE2NTA2NDcy#issuecomment-1636996229%20line%201%20%3E%20injectedScript) Content-Security-Policy:页面设置阻止读取位于 https://testingcf.jsdelivr.net/gh/PipecraftNet/jsdelivr-auto-fallback@main/empty.css?1689519508980 的一项资源("style-src")。 [8:122:18](https://github.com/PipecraftNet/jsdelivr-auto-fallback/issues/8?notification_referrer_id=NT_kwDOAPveaLM3MDAyNTUxMTk0OjE2NTA2NDcy#issuecomment-1636996229%20line%201%20%3E%20injectedScript) Content-Security-Policy:页面设置阻止读取位于 https://test1.jsdelivr.net/gh/PipecraftNet/jsdelivr-auto-fallback@main/empty.css?1689519508980 的一项资源("style-src")。 [8:122:18](https://github.com/PipecraftNet/jsdelivr-auto-fallback/issues/8?notification_referrer_id=NT_kwDOAPveaLM3MDAyNTUxMTk0OjE2NTA2NDcy#issuecomment-1636996229%20line%201%20%3E%20injectedScript) Content-Security-Policy:页面设置阻止读取位于 data:text/plain;base64, 的一项资源("style-src")。
不愧是小狐狸

@eebssk1
Copy link
Author

eebssk1 commented Jul 16, 2023

Now firefox is giving you headaches.

Content-Security-Policy:页面设置阻止读取位于 https://cdn.jsdelivr.net/gh/PipecraftNet/jsdelivr-auto-fallback@main/empty.css?1689519508980 的一项资源("style-src")。 [8:122:18](https://github.com/PipecraftNet/jsdelivr-auto-fallback/issues/8?notification_referrer_id=NT_kwDOAPveaLM3MDAyNTUxMTk0OjE2NTA2NDcy#issuecomment-1636996229%20line%201%20%3E%20injectedScript) Content-Security-Policy:页面设置阻止读取位于 https://unpkg.com/gh/PipecraftNet/jsdelivr-auto-fallback@main/empty.css?1689519508980 的一项资源("style-src")。 [8:122:18](https://github.com/PipecraftNet/jsdelivr-auto-fallback/issues/8?notification_referrer_id=NT_kwDOAPveaLM3MDAyNTUxMTk0OjE2NTA2NDcy#issuecomment-1636996229%20line%201%20%3E%20injectedScript) Content-Security-Policy:页面设置阻止读取位于 https://fastly.jsdelivr.net/gh/PipecraftNet/jsdelivr-auto-fallback@main/empty.css?1689519508980 的一项资源("style-src")。 [8:122:18](https://github.com/PipecraftNet/jsdelivr-auto-fallback/issues/8?notification_referrer_id=NT_kwDOAPveaLM3MDAyNTUxMTk0OjE2NTA2NDcy#issuecomment-1636996229%20line%201%20%3E%20injectedScript) Content-Security-Policy:页面设置阻止读取位于 https://gcore.jsdelivr.net/gh/PipecraftNet/jsdelivr-auto-fallback@main/empty.css?1689519508980 的一项资源("style-src")。 [8:122:18](https://github.com/PipecraftNet/jsdelivr-auto-fallback/issues/8?notification_referrer_id=NT_kwDOAPveaLM3MDAyNTUxMTk0OjE2NTA2NDcy#issuecomment-1636996229%20line%201%20%3E%20injectedScript) Content-Security-Policy:页面设置阻止读取位于 https://cdn.zenless.top/gh/PipecraftNet/jsdelivr-auto-fallback@main/empty.css?1689519508980 的一项资源("style-src")。 [8:122:18](https://github.com/PipecraftNet/jsdelivr-auto-fallback/issues/8?notification_referrer_id=NT_kwDOAPveaLM3MDAyNTUxMTk0OjE2NTA2NDcy#issuecomment-1636996229%20line%201%20%3E%20injectedScript) Content-Security-Policy:页面设置阻止读取位于 https://testingcf.jsdelivr.net/gh/PipecraftNet/jsdelivr-auto-fallback@main/empty.css?1689519508980 的一项资源("style-src")。 [8:122:18](https://github.com/PipecraftNet/jsdelivr-auto-fallback/issues/8?notification_referrer_id=NT_kwDOAPveaLM3MDAyNTUxMTk0OjE2NTA2NDcy#issuecomment-1636996229%20line%201%20%3E%20injectedScript) Content-Security-Policy:页面设置阻止读取位于 https://test1.jsdelivr.net/gh/PipecraftNet/jsdelivr-auto-fallback@main/empty.css?1689519508980 的一项资源("style-src")。 [8:122:18](https://github.com/PipecraftNet/jsdelivr-auto-fallback/issues/8?notification_referrer_id=NT_kwDOAPveaLM3MDAyNTUxMTk0OjE2NTA2NDcy#issuecomment-1636996229%20line%201%20%3E%20injectedScript) Content-Security-Policy:页面设置阻止读取位于 data:text/plain;base64, 的一项资源("style-src")。 不愧是小狐狸

Consider trying with unsafeWindow or override CSP with some magic.

@eebssk1
Copy link
Author

eebssk1 commented Jul 16, 2023

Now firefox is giving you headaches.
Content-Security-Policy:页面设置阻止读取位于 https://cdn.jsdelivr.net/gh/PipecraftNet/jsdelivr-auto-fallback@main/empty.css?1689519508980 的一项资源("style-src")。 [8:122:18](https://github.com/PipecraftNet/jsdelivr-auto-fallback/issues/8?notification_referrer_id=NT_kwDOAPveaLM3MDAyNTUxMTk0OjE2NTA2NDcy#issuecomment-1636996229%20line%201%20%3E%20injectedScript) Content-Security-Policy:页面设置阻止读取位于 https://unpkg.com/gh/PipecraftNet/jsdelivr-auto-fallback@main/empty.css?1689519508980 的一项资源("style-src")。 [8:122:18](https://github.com/PipecraftNet/jsdelivr-auto-fallback/issues/8?notification_referrer_id=NT_kwDOAPveaLM3MDAyNTUxMTk0OjE2NTA2NDcy#issuecomment-1636996229%20line%201%20%3E%20injectedScript) Content-Security-Policy:页面设置阻止读取位于 https://fastly.jsdelivr.net/gh/PipecraftNet/jsdelivr-auto-fallback@main/empty.css?1689519508980 的一项资源("style-src")。 [8:122:18](https://github.com/PipecraftNet/jsdelivr-auto-fallback/issues/8?notification_referrer_id=NT_kwDOAPveaLM3MDAyNTUxMTk0OjE2NTA2NDcy#issuecomment-1636996229%20line%201%20%3E%20injectedScript) Content-Security-Policy:页面设置阻止读取位于 https://gcore.jsdelivr.net/gh/PipecraftNet/jsdelivr-auto-fallback@main/empty.css?1689519508980 的一项资源("style-src")。 [8:122:18](https://github.com/PipecraftNet/jsdelivr-auto-fallback/issues/8?notification_referrer_id=NT_kwDOAPveaLM3MDAyNTUxMTk0OjE2NTA2NDcy#issuecomment-1636996229%20line%201%20%3E%20injectedScript) Content-Security-Policy:页面设置阻止读取位于 https://cdn.zenless.top/gh/PipecraftNet/jsdelivr-auto-fallback@main/empty.css?1689519508980 的一项资源("style-src")。 [8:122:18](https://github.com/PipecraftNet/jsdelivr-auto-fallback/issues/8?notification_referrer_id=NT_kwDOAPveaLM3MDAyNTUxMTk0OjE2NTA2NDcy#issuecomment-1636996229%20line%201%20%3E%20injectedScript) Content-Security-Policy:页面设置阻止读取位于 https://testingcf.jsdelivr.net/gh/PipecraftNet/jsdelivr-auto-fallback@main/empty.css?1689519508980 的一项资源("style-src")。 [8:122:18](https://github.com/PipecraftNet/jsdelivr-auto-fallback/issues/8?notification_referrer_id=NT_kwDOAPveaLM3MDAyNTUxMTk0OjE2NTA2NDcy#issuecomment-1636996229%20line%201%20%3E%20injectedScript) Content-Security-Policy:页面设置阻止读取位于 https://test1.jsdelivr.net/gh/PipecraftNet/jsdelivr-auto-fallback@main/empty.css?1689519508980 的一项资源("style-src")。 [8:122:18](https://github.com/PipecraftNet/jsdelivr-auto-fallback/issues/8?notification_referrer_id=NT_kwDOAPveaLM3MDAyNTUxMTk0OjE2NTA2NDcy#issuecomment-1636996229%20line%201%20%3E%20injectedScript) Content-Security-Policy:页面设置阻止读取位于 data:text/plain;base64, 的一项资源("style-src")。 不愧是小狐狸

Consider trying with unsafeWindow or override CSP with some magic.

Or consider using API provided by userscript manager like "GM_addElement"
See
https://violentmonkey.github.io/api/gm/#gm_addelement
https://www.tampermonkey.net/documentation.php#api:GM_addElement
for more information

PipecraftNet added a commit that referenced this issue Jul 17, 2023
@PipecraftNet
Copy link
Owner

Or consider using API provided by userscript manager like "GM_addElement"
See
https://violentmonkey.github.io/api/gm/#gm_addelement
https://www.tampermonkey.net/documentation.php#api:GM_addElement
for more information

这个脚本对 CSP 严格的网站无能为力,所以一开始就放弃支持这些网站了。

刚刚尝试了使用 “GM_addElement” 添加元素。用它确实可以成功添加元素,但是当改变 script, style, img 元素的 href 或 src 属性值时,依然会报 CSP 错误。

“GM_addElement” 至少有些帮助,所以用上它发布了 0.2.4 版本。

还有,Greasemonkey 不支持 “GM_addElement” API。

PipecraftNet added a commit that referenced this issue Jul 17, 2023
@eebssk1
Copy link
Author

eebssk1 commented Jul 18, 2023

Or consider using API provided by userscript manager like "GM_addElement"
See
https://violentmonkey.github.io/api/gm/#gm_addelement
https://www.tampermonkey.net/documentation.php#api:GM_addElement
for more information

这个脚本对 CSP 严格的网站无能为力,所以一开始就放弃支持这些网站了。

刚刚尝试了使用 “GM_addElement” 添加元素。用它确实可以成功添加元素,但是当改变 script, style, img 元素的 href 或 src 属性值时,依然会报 CSP 错误。

“GM_addElement” 至少有些帮助,所以用上它发布了 0.2.4 版本。

还有,Greasemonkey 不支持 “GM_addElement” API。

那还挺恐怖的😂

实际上我用的是violentmonkey🌚

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants