fix: proxy absolute same-origin preview requests
Fixes Preview backend calls built from window.location.origin Routes same-origin fetch, XHR, EventSource, and WebSocket requests through the preview proxy Keeps local full-stack apps working inside the Preview panel
This commit is contained in:
@@ -484,9 +484,35 @@ const PREVIEW_BRIDGE_SCRIPT = String.raw`(() => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const proxiedUrl = (value) => {
|
const proxiedUrl = (value) => {
|
||||||
if (typeof value !== 'string' || !value.startsWith('/')) return value;
|
if (typeof value !== 'string') return value;
|
||||||
if (!shouldProxyPath(value)) return value;
|
if (value.startsWith('/')) {
|
||||||
return proxyBase + value;
|
if (!shouldProxyPath(value)) return value;
|
||||||
|
return proxyBase + value;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const parsed = new URL(value, window.location.href);
|
||||||
|
if (parsed.origin === window.location.origin && shouldProxyPath(parsed.pathname)) {
|
||||||
|
return proxyBase + parsed.pathname + parsed.search + parsed.hash;
|
||||||
|
}
|
||||||
|
} catch {}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
};
|
||||||
|
|
||||||
|
const proxiedWebSocketUrl = (value) => {
|
||||||
|
if (typeof value !== 'string') return value;
|
||||||
|
try {
|
||||||
|
const parsed = new URL(value, window.location.href);
|
||||||
|
const current = new URL(window.location.href);
|
||||||
|
const sameHost = parsed.host === current.host;
|
||||||
|
const isWebSocketProtocol = parsed.protocol === 'ws:' || parsed.protocol === 'wss:';
|
||||||
|
if (sameHost && isWebSocketProtocol && shouldProxyPath(parsed.pathname)) {
|
||||||
|
parsed.pathname = proxyBase + parsed.pathname;
|
||||||
|
return parsed.toString();
|
||||||
|
}
|
||||||
|
} catch {}
|
||||||
|
return value;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (typeof window.fetch === 'function') {
|
if (typeof window.fetch === 'function') {
|
||||||
@@ -529,6 +555,20 @@ const PREVIEW_BRIDGE_SCRIPT = String.raw`(() => {
|
|||||||
Object.defineProperty(OpenChamberPreviewEventSource, 'name', { value: 'EventSource' });
|
Object.defineProperty(OpenChamberPreviewEventSource, 'name', { value: 'EventSource' });
|
||||||
window.EventSource = OpenChamberPreviewEventSource;
|
window.EventSource = OpenChamberPreviewEventSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (typeof window.WebSocket === 'function') {
|
||||||
|
const NativeWebSocket = window.WebSocket;
|
||||||
|
function OpenChamberPreviewAppWebSocket(url, protocols) {
|
||||||
|
const nextUrl = proxiedWebSocketUrl(String(url));
|
||||||
|
return arguments.length === 1
|
||||||
|
? new NativeWebSocket(nextUrl)
|
||||||
|
: new NativeWebSocket(nextUrl, protocols);
|
||||||
|
}
|
||||||
|
OpenChamberPreviewAppWebSocket.prototype = NativeWebSocket.prototype;
|
||||||
|
Object.setPrototypeOf(OpenChamberPreviewAppWebSocket, NativeWebSocket);
|
||||||
|
Object.defineProperty(OpenChamberPreviewAppWebSocket, 'name', { value: 'WebSocket' });
|
||||||
|
window.WebSocket = OpenChamberPreviewAppWebSocket;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const selectorPart = (element) => {
|
const selectorPart = (element) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user