# Request Proxy (请求代理)

- **Summary**: `requestProxy` 是 Five 初始化时的关键参数，用于在发起网络请求前对 URL 进行拦截和修改，常用于鉴权、资源重定向或 CDN 域名替换。
- **Schema**: `(url: string) => string | Promise<string>`
- **Concepts**: 请求拦截、资源重定向、鉴权签名。
- **Configuration**: `FiveInitArgs.requestProxy`。
- **Examples**: CDN 替换、私有化部署鉴权、调试模式。

## Schema

> **Definition**: [FiveInitArgs](../../five/application/fiveInitArgs.d.ts)

```typescript
interface FiveInitArgs {
  /**
   * 请求代理函数
   * @description 在 Five 内部发起任何网络请求（如加载图片、模型、配置）之前调用。
   * @param url - 原始请求 URL
   * @returns 修改后的 URL (string) 或异步返回修改后的 URL (Promise<string>)
   */
  requestProxy?: (url: string) => string | Promise<string>;
}
```

## Concepts

### 拦截时机
Five 内部加载资源（全景图瓦片、3D 模型、纹理贴图等）时，会通过统一的 Fetcher 层发起请求。`requestProxy` 钩子函数会在每次请求发起**前**被触发。

### 核心用途
1.  **域名替换 (CDN Domain Sharding)**: 将资源请求分散到多个 CDN 域名以突破浏览器并发限制。
2.  **鉴权签名 (Authentication)**: 针对私有化部署或受保护资源，在 URL 后追加鉴权 Token (如 SAS Token)。
3.  **资源重定向 (Redirection)**: 在开发环境下将线上资源重定向到本地或测试环境。
4.  **协议适配**: 强制将 `http` 协议升级为 `https`。

## Configuration

`requestProxy` 是 `Five` 构造函数的配置项之一。

| 参数 | 类型 | 默认值 | 说明 |
| :--- | :--- | :--- | :--- |
| `requestProxy` | `(url: string) => string \| Promise<string>` | `undefined` | 代理函数，返回修改后的 URL。支持同步或异步返回。 |

## Examples

### 1. 基础用法：CDN 域名替换

将图片资源请求分散到不同的 CDN 节点，加速加载。

```typescript
const five = new Five({
  requestProxy: (url) => {
    // 简单的字符串替换示例
    return url.replace('//vrlab-public.ljcdn.com/', '//vr-public.realsee-cdn.cn/');
  }
});
```

### 2. 进阶用法：异步鉴权 (Async Auth)

对于需要动态获取 Token 的场景，可以使用 `Promise` 异步返回 URL。

```typescript
const five = new Five({
  requestProxy: async (url) => {
    // 仅对私有桶资源进行签名
    if (url.includes('private-bucket')) {
      const token = await fetchToken(); // 假设 fetchToken 是一个获取鉴权的异步函数
      const separator = url.includes('?') ? '&' : '?';
      return `${url}${separator}token=${token}`;
    }
    return url;
  }
});
```

### 3. 开发调试：本地资源代理

在开发阶段，将特定资源重定向到本地文件。

```typescript
const proxyMap: Record<string, string> = {};

const five = new Five({
  requestProxy: (url) => {
    // 如果该 URL 在映射表中存在（例如通过 <input type="file"> 加载的本地 Blob URL），则使用映射值
    if (proxyMap[url]) {
      console.log(`[Proxy] Redirecting ${url} -> ${proxyMap[url]}`);
      return proxyMap[url];
    }
    return url;
  }
});
```

## Common Pitfalls

1.  **死循环风险**: 不要在 `requestProxy` 内部再次发起会导致 `requestProxy` 触发的 Five 资源请求，否则可能导致递归调用。
2.  **性能损耗**: `requestProxy` 会在**所有**资源请求前触发（包括成百上千个瓦片请求）。请确保该函数执行效率极高，避免进行耗时的同步操作。如果是异步操作，应做好缓存。
3.  **URL 格式**: 确保返回的 URL 格式正确。如果原 URL 包含 Query 参数，拼接 Token 时要注意判断是使用 `?` 还是 `&`。
4.  **缓存一致性**: 如果修改了 URL（例如加了 Token），可能会影响浏览器的缓存命中策略。

## Related

*   [Parameter](./parameter.md): Five 初始化参数总览。
*   [Load External Model](./load-external-model.md): 加载外部模型时也会触发 requestProxy。

---

```yaml
tags: [请求代理, 鉴权, 域名替换, 私有化, 请求拦截, configuration, network, proxy, authentication, CDN, token, url-rewrite, cors]
```
