Transport policy enforcer

Enforce request policies for fetch() or GM_xmlhttpRequest methods with fallback routing

이 스크립트는 직접 설치하는 용도가 아닙니다. 다른 스크립트에서 메타 지시문 // @require https://update.greasyfork.org/scripts/591898/1906160/Transport%20policy%20enforcer.js을(를) 사용하여 포함하는 라이브러리입니다.

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

작성자
SassyRhombus
버전
1.0.0
생성일
2026-08-18
갱신일
2026-08-18
크기
12.3KB
라이선스
BSD-0

Brief

TransportPolicy is a site-agnostic userscript library for routing GM-shaped requests over page-context fetch and/or GM_xmlhttpRequest. It normalises both transports to one response shape, supports one configurable fallback hop, and exposes optional routing events for diagnostics.

The library does not interpret site responses, impose same-origin restrictions, or reject HTTP error statuses. Its only policy inputs are transport availability, transport errors, configured status matches, and an optional predicate.

Usage

Load the library before the calling userscript and add the GM grant/connect entries required by that script's chosen transport:

// @grant    GM_xmlhttpRequest
// @connect  api.example.com
// @require  https://example.invalid/transport-policy.lib.user.js

TransportPolicy.configure({
    transport: 'gm-first',
    fallbackOn: {
        transportError: true,
        statuses: [403, 429, [500, 599]],
        predicate: null,
    },
});

const response = await TransportPolicy.request({
    method: 'GET',
    url: 'https://api.example.com/items',
    responseType: 'json',
});

For callback-oriented callers, xmlHttpRequest accepts onload, onerror, and ontimeout:

const handle = TransportPolicy.xmlHttpRequest({
    url: '/api/items',
    onload: (response) => console.log(response.responseText),
    onerror: (error) => console.error(error),
    ontimeout: (error) => console.error('Timed out', error),
});

handle.abort(); // compatibility no-op

API

TransportPolicy.configure(options)

Shallow-merges options into the live configuration object and returns that object. A configured fallbackOn object therefore replaces the previous configured object.

TransportPolicy.config

The live configuration object. Direct mutations affect subsequent requests.

Key Default Description
transport 'gm-first' One of gm-first, fetch-first, gm-only, or fetch-only.
fallbackOn.transportError true Falls back when the primary transport throws, reports an error, aborts, or times out.
fallbackOn.statuses [403, 429, [500, 599]] Exact status numbers and inclusive [low, high] ranges that trigger fallback. [] disables status fallback.
fallbackOn.predicate null Called as (response, transportUsed). Boolean true forces fallback, boolean false forbids it, and any other result defers to transport-error/status rules. On a transport error, response is undefined.
gmProvider GM API lookup Returns GM.xmlHttpRequest, legacy GM_xmlhttpRequest, or null.
fetchProvider page/global fetch lookup Returns page window.fetch, global fetch, or null.
timeoutMs 30000 Default timeout in milliseconds. Request-level timeout takes precedence; zero disables timeout handling.
onTransportEvent null Optional best-effort event callback. Exceptions from it are ignored.

TransportPolicy.request(details)

Returns a Promise<NormalisedResponse>. details follows the GM_xmlhttpRequest shape, including method, url, headers, data, timeout, responseType, and anonymous. Two policy-only keys are also accepted:

  • transport overrides the configured ordering for this request.
  • fallbackOn is merged over the configured fallbackOn object for this request, so individual rules can be overridden without repeating the others.

Those policy-only keys are removed before dispatch to a provider. Supported fetch response types are text (the default), json, arraybuffer, and blob.

TransportPolicy.xmlHttpRequest(details)

Starts request(details) and dispatches the result through GM-shaped onload, onerror, or ontimeout callbacks. It returns { abort() {} }; aborting through this compatibility shim is intentionally a no-op.

TransportPolicy.TRANSPORTS

The supported ordering names: ['gm-first', 'fetch-first', 'gm-only', 'fetch-only'].

TransportPolicy.matchesStatus(status, list)

Returns whether status matches an exact number or an inclusive range in list.

Decision algorithm

  1. Resolve the chosen policy to a primary transport and, for a *-first policy, a secondary transport.
  2. Attempt the primary. When its provider is unavailable, skip directly to the secondary if one exists; otherwise reject.
  3. If a fallback transport exists, consult the predicate first. A boolean result is authoritative. Otherwise, consult transportError, then the status list.
  4. If no rule calls for fallback, return the primary HTTP response as-is, including non-2xx responses. A primary transport error rejects when fallback is disabled or unavailable by policy.
  5. If fallback is selected, attempt the secondary exactly once and return its response regardless of status. A secondary transport error rejects and includes primaryError or primaryResponse on the error.

No retry or third transport attempt is performed.

Response shape

Both transports resolve to:

{
    status,
    statusText,
    responseText,
    response,
    responseHeaders, // "name: value\r\n" lines
    finalUrl,
    transport,       // 'fetch' or 'gm'
    fellBack,
    primary,         // present after fallback: { transport, status? , error? }
}

For json, fetch preserves the raw text in responseText and puts the parsed value in response. For arraybuffer and blob, responseText is an empty string.

Transport rejections carry error.transport. When the secondary rejects, the error also carries the normalised primaryResponse or the original primaryError.

Events

onTransportEvent receives objects with type, transport, url, and method, plus applicable status, error, or reason fields.

Type Meaning
attempt A transport was selected for an attempt. This is emitted even when its provider proves unavailable.
fallback The primary is being left. transport identifies that primary; reason is transport-error, status, predicate, or unavailable.
resolved The request resolved; transport identifies the returned response.
rejected The request rejected; transport identifies the final failing transport.

For example, a GM 403 followed by a successful fetch emits attempt(gm), fallback(gm, status), attempt(fetch), and resolved(fetch).

Caveats

  • Page-context fetch obeys browser CORS rules for cross-origin URLs. A URL being accepted by the policy does not mean the browser will permit the fetch.
  • Fetch cannot set forbidden request headers such as Cookie or Origin; the browser controls them. It always uses credentials: 'include', cache: 'no-store', and redirect: 'follow'.
  • The GM path requires an appropriate @grant (GM_xmlhttpRequest) and cross-origin targets commonly require matching @connect metadata. With @grant none, only page/global fetch is normally available.
  • anonymous is passed through to GM providers but has no fetch equivalent.
  • The fallback predicate runs application code in the request path. If it throws, the request rejects.