@gylautorun/dev-proxy-cookie 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,14 +1,44 @@
1
1
  /**
2
- * Replace outbound Cookie with the dev file cookie.
3
- * Browsers send `Cookie` when `withCredentials` is true; merging with file cookie often yields duplicate
4
- * names (e.g. two JSESSIONID) and many servers honor the first value — the stale browser session.
2
+ * 应用开发环境 Cookie 到代理请求头
3
+ *
4
+ * 将文件中读取的 Cookie 设置到代理请求中,替换浏览器发送的 Cookie。
5
+ * 这是必要的,因为当 withCredentials 为 true 时,浏览器会发送其自身的 Cookie,
6
+ * 与文件中的 Cookie 合并可能导致重复的 Cookie 名称(如两个 JSESSIONID),
7
+ * 而服务器通常会优先使用第一个值(浏览器的旧会话)。
8
+ *
9
+ * @param proxyReq - 代理请求对象
10
+ * @param cookie - 要设置的 Cookie 字符串
5
11
  */
6
12
  export function applyDevCookieHeader(
7
- proxyReq: { removeHeader(name: string): void; setHeader(name: string, value: string): void },
13
+ proxyReq: { removeHeader(name: string): void; setHeader(name: string, value: string): void; getHeader?(name: string): string | undefined },
8
14
  cookie: string
9
15
  ): void {
10
- if (!cookie) return;
16
+ console.log('[applyDevCookieHeader] === START ===');
17
+ console.log('[applyDevCookieHeader] Cookie to apply:', cookie ? `(length: ${cookie.length})` : '(empty)');
18
+
19
+ if (!cookie) {
20
+ console.log('[applyDevCookieHeader] Cookie is empty, returning');
21
+ console.log('[applyDevCookieHeader] === END ===');
22
+ return;
23
+ }
24
+
25
+ // 尝试获取当前的 cookie 头(如果有)
26
+ const existingCookie = proxyReq.getHeader?.('Cookie');
27
+ console.log('[applyDevCookieHeader] Cookie current:', existingCookie ? `(length: ${String(existingCookie).length})` : '(none)');
28
+
29
+ // 如果现有 Cookie 与要设置的 Cookie 相同,直接跳过处理
30
+ if (existingCookie === cookie) {
31
+ console.log('[applyDevCookieHeader] Cookie is already set, skipping');
32
+ console.log('[applyDevCookieHeader] === END ===');
33
+ return;
34
+ }
35
+
11
36
  proxyReq.removeHeader('cookie');
12
37
  proxyReq.removeHeader('Cookie');
13
38
  proxyReq.setHeader('Cookie', cookie);
39
+
40
+ // 验证是否设置成功
41
+ const newCookie = proxyReq.getHeader?.('Cookie');
42
+ console.log('[applyDevCookieHeader] Cookie new:', newCookie ? `(length: ${String(newCookie).length})` : '(failed)');
43
+ console.log('[applyDevCookieHeader] === END ===');
14
44
  }
package/src/proxy/core.ts CHANGED
@@ -1,3 +1,11 @@
1
+ /**
2
+ * 自动代理 Cookie 核心模块
3
+ *
4
+ * 提供完整的开发环境代理解决方案,支持 HTTP 和 WebSocket 代理,
5
+ * 自动从文件读取 Cookie 并注入到代理请求中。
6
+ *
7
+ * @module core
8
+ */
1
9
  import * as http from 'http';
2
10
  import * as net from 'net';
3
11
  import * as fs from 'fs';
@@ -8,6 +16,12 @@ import httpProxy from 'http-proxy';
8
16
  import { CookieReader, CookieWatcher, watchCookieFile } from '../utils';
9
17
  import { applyDevCookieHeader } from './apply-dev-cookie-header';
10
18
 
19
+ /**
20
+ * 错误回调函数类型
21
+ * @param err - 错误对象
22
+ * @param req - 请求对象
23
+ * @param res - 响应对象或 Socket
24
+ */
11
25
  export type ErrorCallback = (err: Error, req: IncomingMessage, res: ServerResponse | net.Socket) => void;
12
26
 
13
27
  interface ProxyServer {
@@ -48,6 +62,12 @@ export interface AutoProxyCookieOptions {
48
62
  autoRestart?: boolean;
49
63
  restartMarkerFile?: string;
50
64
  proxyMap?: Record<string, string>;
65
+ /**
66
+ * 需要代理的路径前缀列表(默认代理到 target)
67
+ * 例如: ['/api', '/digital-platform']
68
+ * 如果请求路径匹配这些前缀之一,将被代理到 target
69
+ */
70
+ proxyPaths?: string[];
51
71
  ignorePaths?: string[];
52
72
  ws?: boolean;
53
73
  changeOrigin?: boolean;
@@ -60,25 +80,50 @@ export interface AutoProxyCookieOptions {
60
80
  cookiePathRewrite?: false | string | { [oldPath: string]: string };
61
81
  headers?: { [header: string]: string };
62
82
  hooks?: ProxyHooks;
83
+ /**
84
+ * 是否启用文件监听
85
+ * - 'auto': 自动(如果 isDev 为 true,则启用监听)
86
+ * - true: 强制启用监听
87
+ * - false: 禁用监听
88
+ *
89
+ * 默认值: 'auto'
90
+ */
91
+ watch?: 'auto' | boolean;
63
92
  /**
64
93
  * 是否为开发环境(优先级最高)
65
94
  * 设置此参数后,将直接决定是否启用文件监听:
66
95
  * - true: 启用监听(开发模式)
67
96
  * - false: 禁用监听(生产模式)
68
- *
97
+ *
69
98
  * 使用示例: isDev: process.env.NODE_ENV === 'development'
70
99
  */
71
100
  isDev?: boolean;
72
101
  }
73
102
 
103
+ /**
104
+ * 自动代理 Cookie 类
105
+ *
106
+ * 提供完整的开发环境代理解决方案,支持 HTTP 和 WebSocket 代理,
107
+ * 自动从文件读取 Cookie 并注入到代理请求中。
108
+ */
74
109
  export class AutoProxyCookie {
110
+ /** 合并后的配置选项 */
75
111
  private options: AutoProxyCookieOptions & { hooks: Required<ProxyHooks> };
112
+ /** 当前 Cookie 值 */
76
113
  private currentCookie: string = '';
114
+ /** Vite 开发服务器实例 */
77
115
  private server: ViteDevServer | null = null;
116
+ /** HTTP 代理服务器实例 */
78
117
  private proxyServer: ProxyServer | null = null;
118
+ /** Cookie 文件监听器 */
79
119
  private watcher: CookieWatcher | null = null;
120
+ /** Cookie 文件读取器 */
80
121
  private cookieReader: CookieReader;
81
122
 
123
+ /**
124
+ * 构造函数
125
+ * @param options - 配置选项
126
+ */
82
127
  constructor(options: AutoProxyCookieOptions) {
83
128
  const defaultHooks: Required<ProxyHooks> = {
84
129
  onProxyReq: () => {},
@@ -100,6 +145,7 @@ export class AutoProxyCookie {
100
145
  autoRestart: false,
101
146
  restartMarkerFile: '.cookie-restart-marker',
102
147
  proxyMap: {},
148
+ proxyPaths: [],
103
149
  ignorePaths: [],
104
150
  ws: true,
105
151
  changeOrigin: true,
@@ -113,9 +159,13 @@ export class AutoProxyCookie {
113
159
  headers: {},
114
160
  ...mergedOptions,
115
161
  };
116
- this.cookieReader = new CookieReader({ cookieFile: options.cookieFile });
162
+ this.cookieReader = new CookieReader({ cookieFile: options.cookieFile }, options.debug ?? false);
117
163
  }
118
164
 
165
+ /**
166
+ * Cookie 变化处理函数
167
+ * @param newCookie - 新的 Cookie 值
168
+ */
119
169
  private handleCookieChange = (newCookie: string): void => {
120
170
  if (newCookie !== this.currentCookie) {
121
171
  this.currentCookie = newCookie;
@@ -133,19 +183,50 @@ export class AutoProxyCookie {
133
183
  }
134
184
  };
135
185
 
186
+ /**
187
+ * 根据请求路径获取代理目标 URL
188
+ * @param req - HTTP 请求对象
189
+ * @returns 代理目标 URL
190
+ */
136
191
  private getProxyUrl(req: IncomingMessage): string {
137
- const pathname = req.url?.split('?')[0] || '/';
192
+ const fullUrl = req.url || '/';
193
+ const pathname = new URL(fullUrl, 'http://localhost').pathname;
138
194
  const proxyMap = this.options.proxyMap || {};
195
+ const proxyPaths = this.options.proxyPaths || [];
196
+
197
+ this.log('debug', '[AutoProxyCookie] getProxyUrl - Request path:', pathname);
198
+ this.log('debug', '[AutoProxyCookie] getProxyUrl - Available proxyMap paths:', Object.keys(proxyMap));
199
+ this.log('debug', '[AutoProxyCookie] getProxyUrl - Available proxyPaths:', proxyPaths);
139
200
 
201
+ // 首先检查 proxyMap(自定义代理目标)
140
202
  for (const [prefix, target] of Object.entries(proxyMap)) {
141
- if (pathname.startsWith(prefix)) {
203
+ const matches = pathname.startsWith(prefix);
204
+ this.log('debug', '[AutoProxyCookie] getProxyUrl - Checking proxyMap:', prefix, '- matches:', matches);
205
+ if (matches) {
206
+ this.log('debug', '[AutoProxyCookie] getProxyUrl - Matched proxyMap:', prefix, '->', target);
142
207
  return target;
143
208
  }
144
209
  }
145
210
 
211
+ // 然后检查 proxyPaths(默认代理到 target)
212
+ for (const prefix of proxyPaths) {
213
+ const matches = pathname.startsWith(prefix);
214
+ this.log('debug', '[AutoProxyCookie] getProxyUrl - Checking proxyPaths:', prefix, '- matches:', matches);
215
+ if (matches) {
216
+ this.log('debug', '[AutoProxyCookie] getProxyUrl - Matched proxyPaths:', prefix, '->', this.options.target);
217
+ return this.options.target;
218
+ }
219
+ }
220
+
221
+ this.log('debug', '[AutoProxyCookie] getProxyUrl - No match found, using default target:', this.options.target);
146
222
  return this.options.target;
147
223
  }
148
224
 
225
+ /**
226
+ * 判断路径是否应该被忽略(不代理)
227
+ * @param pathname - 请求路径
228
+ * @returns 是否忽略
229
+ */
149
230
  private isIgnoredPath(pathname: string): boolean {
150
231
  const ignorePaths = this.options.ignorePaths || [];
151
232
  return ignorePaths.some(ignored =>
@@ -153,9 +234,16 @@ export class AutoProxyCookie {
153
234
  );
154
235
  }
155
236
 
237
+ /**
238
+ * 日志输出函数
239
+ * @param level - 日志级别
240
+ * @param args - 日志参数
241
+ */
156
242
  private log(level: 'debug' | 'info' | 'warn' | 'error', ...args: any[]): void {
157
243
  const levels: Record<string, number> = { debug: 0, info: 1, warn: 2, error: 3 };
158
- const currentLevel = levels[this.options.logLevel || 'info'];
244
+ // 如果设置了 debug: true,则使用 debug 级别
245
+ const effectiveLogLevel = this.options.debug ? 'debug' : (this.options.logLevel || 'info');
246
+ const currentLevel = levels[effectiveLogLevel];
159
247
  const msgLevel = levels[level];
160
248
 
161
249
  if (msgLevel >= currentLevel) {
@@ -169,6 +257,11 @@ export class AutoProxyCookie {
169
257
  }
170
258
  }
171
259
 
260
+ /**
261
+ * 创建代理服务器配置选项
262
+ * @param target - 代理目标地址
263
+ * @returns 代理服务器配置
264
+ */
172
265
  private createProxyOptions(target: string): ServerOptions {
173
266
  const {
174
267
  ws,
@@ -199,9 +292,24 @@ export class AutoProxyCookie {
199
292
  };
200
293
  }
201
294
 
295
+ /**
296
+ * 代理请求处理函数
297
+ * @param proxyReq - 代理请求对象
298
+ * @param req - 原始请求对象
299
+ * @param res - 响应对象
300
+ * @param _options - 服务器选项
301
+ */
202
302
  private handleOnProxyReq = (proxyReq: any, req: IncomingMessage, res: ServerResponse, _options: ServerOptions): void => {
303
+ console.log('[AutoProxyCookie] === handleOnProxyReq START ===');
304
+ console.log('[AutoProxyCookie] Request URL:', req.method, req.url);
305
+ console.log('[AutoProxyCookie] Current cookie:', this.currentCookie ? `(length: ${this.currentCookie.length})` : '(empty)');
306
+
203
307
  if (this.currentCookie) {
308
+ console.log('[AutoProxyCookie] Applying cookie header...');
204
309
  applyDevCookieHeader(proxyReq, this.currentCookie);
310
+ console.log('[AutoProxyCookie] Cookie header applied successfully');
311
+ } else {
312
+ console.log('[AutoProxyCookie] No cookie to apply - currentCookie is empty!');
205
313
  }
206
314
 
207
315
  this.log('debug', '[AutoProxyCookie] Proxy Request:', req.method, req.url);
@@ -213,8 +321,16 @@ export class AutoProxyCookie {
213
321
  this.log('error', '[AutoProxyCookie] onProxyReq hook error:', (err as Error).message);
214
322
  }
215
323
  }
324
+
325
+ console.log('[AutoProxyCookie] === handleOnProxyReq END ===');
216
326
  };
217
327
 
328
+ /**
329
+ * 代理响应处理函数
330
+ * @param proxyRes - 代理响应对象
331
+ * @param req - 原始请求对象
332
+ * @param res - 响应对象
333
+ */
218
334
  private handleOnProxyRes = (proxyRes: any, req: IncomingMessage, res: ServerResponse): void => {
219
335
  const allowedHeaders = [
220
336
  'Content-Type',
@@ -242,6 +358,12 @@ export class AutoProxyCookie {
242
358
  }
243
359
  };
244
360
 
361
+ /**
362
+ * HTTP 代理错误处理函数
363
+ * @param err - 错误对象
364
+ * @param req - 请求对象
365
+ * @param res - 响应对象或 Socket
366
+ */
245
367
  private handleOnError = (err: Error, req: IncomingMessage, res: ServerResponse | net.Socket): void => {
246
368
  this.log('error', '[AutoProxyCookie] Proxy Error:', err.message);
247
369
  this.log('error', '[AutoProxyCookie] URL:', req.url);
@@ -264,6 +386,12 @@ export class AutoProxyCookie {
264
386
  }
265
387
  };
266
388
 
389
+ /**
390
+ * WebSocket 代理错误处理函数
391
+ * @param err - 错误对象
392
+ * @param req - 请求对象
393
+ * @param socket - WebSocket 连接的 Socket
394
+ */
267
395
  private handleOnWsError = (err: Error, req: IncomingMessage, socket: any): void => {
268
396
  this.log('error', '[AutoProxyCookie] WebSocket Proxy Error:', err.message);
269
397
  this.log('error', '[AutoProxyCookie] WebSocket URL:', req.url);
@@ -281,6 +409,10 @@ export class AutoProxyCookie {
281
409
  }
282
410
  };
283
411
 
412
+ /**
413
+ * 初始化代理中间件
414
+ * @param server - Vite 开发服务器实例
415
+ */
284
416
  async setup(server: ViteDevServer): Promise<void> {
285
417
  this.server = server;
286
418
  this.currentCookie = this.cookieReader.readCookie();
@@ -313,30 +445,52 @@ export class AutoProxyCookie {
313
445
  }
314
446
 
315
447
  server.middlewares.use((req: any, res: any, next: any) => {
316
- const pathname = new URL(req.url || '/', 'http://localhost').pathname;
448
+ const fullUrl = req.url || '/';
449
+ const pathname = new URL(fullUrl, 'http://localhost').pathname;
450
+
451
+ // 始终输出请求信息(不仅仅是 debug 模式)
452
+ console.log('[AutoProxyCookie] === Incoming Request ===');
453
+ console.log('[AutoProxyCookie] Method:', req.method);
454
+ console.log('[AutoProxyCookie] Full URL:', fullUrl);
455
+ console.log('[AutoProxyCookie] Pathname:', pathname);
456
+ console.log('[AutoProxyCookie] Headers:', JSON.stringify(req.headers, null, 2));
317
457
 
318
458
  if (this.isIgnoredPath(pathname)) {
459
+ console.log('[AutoProxyCookie] Path ignored, passing to next middleware');
319
460
  next();
320
461
  return;
321
462
  }
322
463
 
464
+ // 读取 cookie 并更新 currentCookie
323
465
  this.currentCookie = this.cookieReader.readCookie();
466
+ console.log('[AutoProxyCookie] Current cookie:', this.currentCookie ? `(length: ${this.currentCookie.length})` : '(empty)');
467
+ if (this.currentCookie) {
468
+ console.log('[AutoProxyCookie] Cookie preview:', this.currentCookie);
469
+ }
470
+
471
+ // 检查是否匹配代理路径(包括 proxyMap 和 proxyPaths)
472
+ const proxyMapKeys = Object.keys(this.options.proxyMap || {});
473
+ const proxyPaths = this.options.proxyPaths || [];
474
+ const allProxyPrefixes = [...proxyMapKeys, ...proxyPaths];
475
+ const matched = allProxyPrefixes.some(prefix => pathname.startsWith(prefix));
476
+ console.log('[AutoProxyCookie] Path matches proxy rules:', matched);
324
477
 
325
478
  if (this.proxyServer) {
326
479
  const target = this.getProxyUrl(req);
327
- if (this.options.debug || this.options.logLevel === 'debug') {
328
- this.log('info', `[AutoProxyCookie] ${pathname} -> ${target}`);
329
- }
480
+ console.log(`[AutoProxyCookie] Proxying ${req.method} ${pathname} -> ${target}`);
330
481
 
331
482
  const proxyOptions = this.createProxyOptions(target);
332
483
 
333
484
  try {
485
+ console.log('[AutoProxyCookie] Calling proxyServer.web...');
334
486
  this.proxyServer.web(req, res, proxyOptions);
487
+ console.log('[AutoProxyCookie] proxyServer.web called successfully');
335
488
  } catch (err: any) {
336
- this.log('error', '[AutoProxyCookie] Proxy web error:', err.message);
489
+ console.error('[AutoProxyCookie] Proxy web error:', err.message);
337
490
  next(err);
338
491
  }
339
492
  } else {
493
+ console.log('[AutoProxyCookie] No proxy server, passing to next middleware');
340
494
  next();
341
495
  }
342
496
  });
@@ -376,6 +530,9 @@ export class AutoProxyCookie {
376
530
  }
377
531
  }
378
532
 
533
+ /**
534
+ * 启动 Cookie 文件监听
535
+ */
379
536
  private startFileWatch(): void {
380
537
  // 判断是否应该启用监听
381
538
  // isDev 参数优先级最高
@@ -407,6 +564,9 @@ export class AutoProxyCookie {
407
564
  }
408
565
  }
409
566
 
567
+ /**
568
+ * 停止代理服务
569
+ */
410
570
  stop(): void {
411
571
  if (this.watcher) {
412
572
  this.watcher.stop();
@@ -419,11 +579,20 @@ export class AutoProxyCookie {
419
579
  this.log('info', '[AutoProxyCookie] Stopped');
420
580
  }
421
581
 
582
+ /**
583
+ * 获取当前 Cookie 值
584
+ * @returns 当前 Cookie 字符串
585
+ */
422
586
  getCurrentCookie(): string {
423
587
  return this.currentCookie;
424
588
  }
425
589
  }
426
590
 
591
+ /**
592
+ * 创建 AutoProxyCookie 实例
593
+ * @param options - 配置选项
594
+ * @returns AutoProxyCookie 实例
595
+ */
427
596
  export function createAutoProxyCookie(options: AutoProxyCookieOptions): AutoProxyCookie {
428
597
  return new AutoProxyCookie(options);
429
598
  }
@@ -1,5 +1,10 @@
1
+ /**
2
+ * 代理模块导出文件
3
+ *
4
+ * 包含 Vue CLI 和 Vite 的代理配置实现,提供完整的开发环境代理解决方案。
5
+ *
6
+ * @module proxy
7
+ */
1
8
  export * from './core';
2
- export * from './vite-plugin';
3
- export * from './vite-cookie-plugin';
9
+ export * from './vite-middleware-plugin';
4
10
  export * from './vue-proxy-config';
5
- export * from './vite-adapter';
@@ -0,0 +1,158 @@
1
+ /**
2
+ * Vite 中间件代理插件模块
3
+ *
4
+ * 提供基于中间件的 Vite 代理功能,支持自动注入 Cookie。
5
+ * 此实现使用 http-proxy 直接处理请求,确保 Cookie 正确注入。
6
+ *
7
+ * @module vite-middleware-plugin
8
+ */
9
+ import type { IncomingMessage, ServerResponse } from 'http';
10
+ import { CookieReader } from '../utils/cookie-reader';
11
+
12
+ /**
13
+ * Vite 中间件代理 Cookie 插件配置选项
14
+ */
15
+ export interface ViteMiddlewareProxyOptions {
16
+ /** Cookie 文件路径 */
17
+ cookieFile: string;
18
+ /** 默认代理目标地址 */
19
+ target: string;
20
+ /** 是否启用调试日志 */
21
+ debug?: boolean;
22
+ /**
23
+ * 代理路径映射表
24
+ * 键:路径前缀,值:代理目标地址
25
+ */
26
+ proxyMap?: Record<string, string>;
27
+ /**
28
+ * 需要代理的路径前缀列表(使用默认 target)
29
+ */
30
+ proxyPaths?: string[];
31
+ /**
32
+ * 需要忽略的路径前缀列表(不代理)
33
+ */
34
+ ignorePaths?: string[];
35
+ }
36
+
37
+ /**
38
+ * 判断路径是否应该被忽略(不代理)
39
+ */
40
+ function isIgnoredPath(pathname: string, ignorePaths: string[]): boolean {
41
+ return ignorePaths.some(ignored => pathname.startsWith(ignored));
42
+ }
43
+
44
+ /**
45
+ * 判断路径是否应该被代理
46
+ */
47
+ function shouldProxy(pathname: string, proxyPrefixes: string[]): boolean {
48
+ return proxyPrefixes.some(prefix => pathname.startsWith(prefix));
49
+ }
50
+
51
+ /**
52
+ * 获取代理目标地址
53
+ */
54
+ function getProxyTarget(pathname: string, proxyMap: Record<string, string>, defaultTarget: string): string {
55
+ for (const [prefix, target] of Object.entries(proxyMap)) {
56
+ if (pathname.startsWith(prefix)) {
57
+ return target;
58
+ }
59
+ }
60
+ return defaultTarget;
61
+ }
62
+
63
+ /**
64
+ * 创建 Vite 中间件代理 Cookie 插件
65
+ *
66
+ * @param options - 插件配置选项
67
+ * @returns Vite 插件对象
68
+ */
69
+ export function viteMiddlewareProxy(options: ViteMiddlewareProxyOptions): any {
70
+ const {
71
+ cookieFile,
72
+ target,
73
+ debug = false,
74
+ proxyMap = {},
75
+ proxyPaths = [],
76
+ ignorePaths = [],
77
+ } = options;
78
+
79
+ // 创建 Cookie 读取器
80
+ const cookieReader = new CookieReader({ cookieFile }, debug);
81
+ let currentCookie = cookieReader.readCookie();
82
+
83
+ // 合并所有代理路径前缀
84
+ const allProxyPrefixes = [
85
+ ...Object.keys(proxyMap),
86
+ ...proxyPaths,
87
+ ];
88
+
89
+ return {
90
+ name: 'vite-middleware-proxy',
91
+ apply: 'serve',
92
+
93
+ configureServer(server: any) {
94
+ // 延迟加载 http-proxy 以避免启动时的兼容性问题
95
+ const httpProxy = require('http-proxy');
96
+ const proxyServer = httpProxy.createProxyServer({});
97
+
98
+ // 监听 Cookie 文件变化
99
+ if (debug) {
100
+ console.log('[ViteMiddlewareProxy] Watching cookie file:', cookieFile);
101
+ }
102
+
103
+ // 添加中间件
104
+ server.middlewares.use((req: IncomingMessage, res: ServerResponse, next: () => void) => {
105
+ const pathname = new URL(req.url || '/', 'http://localhost').pathname;
106
+
107
+ // 检查是否需要忽略
108
+ if (isIgnoredPath(pathname, ignorePaths)) {
109
+ if (debug) {
110
+ console.log('[ViteMiddlewareProxy] Ignoring:', pathname);
111
+ }
112
+ next();
113
+ return;
114
+ }
115
+
116
+ // 检查是否需要代理
117
+ if (!shouldProxy(pathname, allProxyPrefixes)) {
118
+ next();
119
+ return;
120
+ }
121
+
122
+ // 获取代理目标
123
+ const proxyTarget = getProxyTarget(pathname, proxyMap, target);
124
+
125
+ if (debug) {
126
+ console.log('[ViteMiddlewareProxy] Proxying:', req.method, pathname, '->', proxyTarget);
127
+ }
128
+
129
+ // 读取最新的 Cookie
130
+ currentCookie = cookieReader.readCookie();
131
+
132
+ // 注入 Cookie
133
+ if (currentCookie) {
134
+ if (debug) {
135
+ console.log('[ViteMiddlewareProxy] Injecting cookie:', `(length: ${currentCookie.length})`);
136
+ }
137
+ (req as any).headers['cookie'] = currentCookie;
138
+ (req as any).headers['Cookie'] = currentCookie;
139
+ }
140
+
141
+ // 代理请求
142
+ proxyServer.web(req, res, {
143
+ target: proxyTarget,
144
+ changeOrigin: true,
145
+ secure: false,
146
+ ignorePath: false,
147
+ });
148
+ });
149
+
150
+ // 错误处理
151
+ proxyServer.on('error', (err: Error, req: IncomingMessage) => {
152
+ console.error('[ViteMiddlewareProxy] Proxy error:', err.message, 'for', req.url);
153
+ });
154
+ },
155
+ };
156
+ }
157
+
158
+ export default viteMiddlewareProxy;