| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 |
- "use strict";
- var __importDefault = (this && this.__importDefault) || function (mod) {
- return (mod && mod.__esModule) ? mod : { "default": mod };
- };
- Object.defineProperty(exports, "__esModule", { value: true });
- exports.previewProxy = previewProxy;
- const http_1 = __importDefault(require("http"));
- const VITE_HOST = "127.0.0.1";
- const VITE_PORT = 5199;
- // 这些 header 需要从代理响应中剔除(hop-by-hop)
- const HOP_BY_HOP = new Set([
- "transfer-encoding",
- "connection",
- "keep-alive",
- "proxy-connection",
- "proxy-authenticate",
- "proxy-authorization",
- "te",
- "trailers",
- "upgrade",
- ]);
- /**
- * 将 /preview/* 请求代理到 Vite dev server。
- * 对 HTML 响应自动重写路径,给所有根绝对路径加上 /ads/preview/ 前缀,
- * 确保浏览器通过 nginx 正确加载资源。
- */
- function previewProxy(req, res) {
- // Express mount 会剥离 /preview 前缀,req.url 即 Vite 需要的路径
- const targetPath = req.url || "/";
- console.log(`[preview:proxy] ${req.method} ${targetPath}`);
- // 过滤请求 headers(去掉 hop-by-hop,设置正确的 host)
- const reqHeaders = {};
- for (const [key, value] of Object.entries(req.headers)) {
- if (value === undefined)
- continue;
- const lk = key.toLowerCase();
- if (lk === "host")
- continue;
- if (lk === "connection" || lk === "keep-alive" || lk === "upgrade")
- continue;
- reqHeaders[key] = Array.isArray(value) ? value.join(", ") : value;
- }
- reqHeaders["host"] = `${VITE_HOST}:${VITE_PORT}`;
- const proxyReq = http_1.default.request({
- hostname: VITE_HOST,
- port: VITE_PORT,
- path: targetPath,
- method: req.method,
- headers: reqHeaders,
- }, (proxyRes) => {
- const contentType = (proxyRes.headers["content-type"] || "");
- const isHtml = contentType.includes("text/html");
- // 复制响应 headers(过滤 hop-by-hop)
- const resHeaders = {};
- for (const [key, value] of Object.entries(proxyRes.headers)) {
- if (HOP_BY_HOP.has(key.toLowerCase()))
- continue;
- if (value !== undefined && value !== null) {
- resHeaders[key] = Array.isArray(value) ? value.join(", ") : value;
- }
- }
- res.status(proxyRes.statusCode || 200);
- if (isHtml) {
- const chunks = [];
- proxyRes.on("data", (chunk) => chunks.push(chunk));
- proxyRes.on("end", () => {
- let html = Buffer.concat(chunks).toString("utf-8");
- // 将 src="/..." 和 href="/..." 重写为 /ads/preview/...
- // 匹配 root-absolute 路径:以 / 开头,后跟非 / 字符(避免匹配 //)
- html = html.replace(/(src|href)="\/([^/][^"]*)"/g, '$1="/ads/preview/$2"');
- const body = Buffer.from(html, "utf-8");
- resHeaders["content-type"] = "text/html; charset=utf-8";
- resHeaders["content-length"] = String(body.length);
- res.set(resHeaders);
- res.send(body);
- });
- }
- else {
- res.set(resHeaders);
- proxyRes.pipe(res);
- }
- });
- proxyReq.on("error", (err) => {
- console.error(`[preview:proxy] ${err.message}`);
- if (!res.headersSent) {
- res.status(502).json({ error: "Preview server not available" });
- }
- });
- // POST/PUT/PATCH 请求需要转发 body
- if (req.method === "POST" || req.method === "PUT" || req.method === "PATCH") {
- req.pipe(proxyReq);
- }
- else {
- proxyReq.end();
- }
- }
- //# sourceMappingURL=previewProxy.js.map
|