ignis/packages/shim/src/request-url.js
2026-06-03 01:15:27 +02:00

96 lines
2.3 KiB
JavaScript

// Override window.requestUrl to proxy external requests through our server, bypassing CORS.
// Obsidian sets window.requestUrl in app.js, so we override it after app.js loads.
import { isSameOrigin } from "./util/url.js";
import { arrayBufferToBase64, base64ToArrayBuffer } from "./util/base64.js";
async function proxyRequestUrl(request) {
if (typeof request === "string") {
request = { url: request };
}
// Same-origin requests don't need the proxy.
if (isSameOrigin(request.url)) {
const res = await fetch(request.url, {
method: request.method || "GET",
headers: request.headers || {},
body: request.body,
});
const arrayBuf = await res.arrayBuffer();
return makeResponse(
request,
res.status,
Object.fromEntries(res.headers),
arrayBuf,
);
}
// Cross-origin: route through server proxy
let body = request.body;
let binary = false;
if (body instanceof ArrayBuffer) {
body = arrayBufferToBase64(body);
binary = true;
}
const res = await fetch("/api/proxy", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
url: request.url,
method: request.method || "GET",
headers: request.headers || {},
body,
binary,
}),
});
if (!res.ok) {
const err = await res
.json()
.catch(() => ({ error: "Proxy request failed" }));
throw new Error(err.error);
}
const proxyResult = await res.json();
const arrayBuf = base64ToArrayBuffer(proxyResult.body);
return makeResponse(
request,
proxyResult.status,
proxyResult.headers,
arrayBuf,
);
}
function makeResponse(request, status, headers, arrayBuf) {
const text = new TextDecoder().decode(arrayBuf);
let json;
try {
json = JSON.parse(text);
} catch {
json = null;
}
return { status, headers, arrayBuffer: arrayBuf, text, json };
}
export function installRequestUrlShim() {
// Obsidian sets window.requestUrl in app.js. We override it once the page loads.
// Use a getter so it intercepts even if app.js sets it later.
let _original = null;
Object.defineProperty(window, "requestUrl", {
get() {
return proxyRequestUrl;
},
set(val) {
_original = val;
},
configurable: true,
});
}