CORS-via-GM

CORS via Greasemonkey/Tampermonkey

// ==UserScript==
// @name         CORS-via-GM
// @description  CORS via Greasemonkey/Tampermonkey
// @version      2.0
// @include      /^(file:///.*/index.html|https?://(127.0.0.1|192.168.\d+.\d+|localhost)(:\d+)?/(([^/]*/)?bundled/)?(index.html)?)(\?.*|$)/
// @include      /\b(pages\.dev|onrender\.com)\b/
// @include      /\b(?:github.io|gitlab.io|glitch.me|js.org|eu.org|web.app|netlify.(?:com|app)|now.sh|vercel.(?:com|app)|herokuapp.com|neocities.org)/
// @include      /https?://\w+?fork\.org/
// @connect      *
// @grant        GM_xmlhttpRequest
// @namespace    https://gf.qytechs.cn/users/882700
// @license      WTFPL
// ==/UserScript==


const CORSViaGM = document.body.appendChild(Object.assign(document.createElement('div'), { id: 'CORSViaGM' }))

addEventListener('fetchViaGM', e => GM_fetch(e.detail.forwardingFetch))

CORSViaGM.init = function (window = unsafeWindow) {
  if (!window) throw 'The `window` parameter must be passed in!'
  window.fetch = window.fetchViaGM = fetchViaGM.bind(window)

  // Support for service worker
  window.forwardingFetch = new BroadcastChannel('forwardingFetch')
  window.forwardingFetch.onmessage = async e => {
    const req = e.data
    const { url } = req
    const res = await fetchViaGM(url, req)
    const response = await res.blob()
    window.forwardingFetch.postMessage({ type: 'fetchResponse', url, response })
  }

  window._CORSViaGM && window._CORSViaGM.inited.done()

  const info = '🙉 CORS-via-GM initiated!'
  console.info(info)
  return info
}


function GM_fetch(p) {
  GM_xmlhttpRequest({
    ...p.init,
    url: p.url,
    method: p.init.method || 'GET',
    data: p.body,
    responseType: 'blob', // !!important
    onload: responseDetails => p.res(new Response(
      responseDetails.response,
      {
        status: responseDetails.status,
        statusText: responseDetails.statusText,
        headers: convertHeaders(responseDetails.responseHeaders)
      }
    ))
  })
}

function fetchViaGM(url, init) {
  let res
  const p = new Promise(r => res = r)
  p.res = res
  p.url = url
  p.init = init || {}
  dispatchEvent(new CustomEvent('fetchViaGM', { detail: { forwardingFetch: p } }))
  return p
}


function convertHeaders(string) {
  return JSON.parse(`{${string.trim().split(/(?:\r?\n(?!(?:.(?!: ))+\r?\n))+/).map(_ => _.replaceAll('"', '\\"').replace(/[\r\n]/g, '; ').replace(/^(.+?):\s*(.+)/s, '"$1": "$2"')).join(',\n')}}`)
}

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址