🚀 TMDB Proxy

Cloudflare Pages 反向代理服务
Cloudflare Pages Ready

📋 项目简介

这是一个专为 TMDB (The Movie Database) 设计的高性能反向代理解决方案,完美适配 Cloudflare Pages 环境。

它能够帮助您绕过 API 限制、加速图片加载、解决 CORS 跨域问题,并提供企业级的性能和可靠性。

高性能
🌐 全球 CDN
🔒 CORS 安全
💾 智能缓存

🚀 快速部署指南

  1. 访问 Cloudflare Dashboard 并登录您的账户
  2. 导航到 Workers & PagesCreate applicationCreate Pages project
  3. 选择 Connect to GitDirect Upload 方式
  4. 上传或连接包含以下文件的项目:
    • index.html - 前端页面
    • functions/api/[[path]].js - API 代理逻辑
    • functions/_middleware.js - 全局中间件
    • _headers - 安全头配置
  5. 点击 "Save and Deploy" 部署您的 Pages 项目
  6. 记录并保存您的 Pages URL (例如: https://your-project.pages.dev)
  7. 在您的前端应用中配置反代地址,开始使用!

🔧 Functions 代码

Cloudflare Pages Functions 是实现 API 代理的核心:

/** * Cloudflare Pages Functions - TMDB Proxy API * 文件位置: functions/api/[[path]].js */ export async function onRequest(context) { const { request, env, params } = context; const url = new URL(request.url); // 移除 /api 前缀,构建TMDB目标URL const path = url.pathname.replace(/^\/api/, ''); const targetUrl = \`https://api.themoviedb.org\${path}\${url.search}\`; // 设置CORS头 const corsHeaders = { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type, Authorization', }; // 处理OPTIONS预检请求 if (request.method === 'OPTIONS') { return new Response(null, { status: 204, headers: corsHeaders }); } try { // 检查是否是图片请求(TMDB图片代理) if (path.startsWith('/t/')) { return await handleImageRequest(request, path, url.search, corsHeaders); } // 处理API请求 return await handleApiRequest(request, targetUrl, corsHeaders); } catch (error) { return new Response(JSON.stringify({ error: 'Proxy Error', message: error.message, timestamp: new Date().toISOString() }), { status: 500, headers: { 'Content-Type': 'application/json', ...corsHeaders } }); } } async function handleApiRequest(request, targetUrl, corsHeaders) { const cacheKey = new Request(targetUrl, { method: 'GET', headers: { 'Accept': 'application/json' } }); const cache = caches.default; let response = await cache.match(cacheKey); if (!response) { response = await fetch(targetUrl, { method: request.method, headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', 'Accept': request.headers.get('Accept') || 'application/json', 'Authorization': request.headers.get('Authorization') || '', } }); if (response.ok) { const responseToCache = response.clone(); const cacheHeaders = new Headers(responseToCache.headers); cacheHeaders.set('Cache-Control', 'public, max-age=600'); const cachedResponse = new Response(responseToCache.body, { status: responseToCache.status, headers: cacheHeaders }); context.waitUntil(cache.put(cacheKey, cachedResponse)); } } const newHeaders = new Headers(response.headers); Object.entries(corsHeaders).forEach(([key, value]) => { newHeaders.set(key, value); }); return new Response(response.body, { status: response.status, statusText: response.statusText, headers: newHeaders }); } async function handleImageRequest(request, path, search, corsHeaders) { const targetUrl = \`https://image.tmdb.org\${path}\${search}\`; const cacheKey = new Request(targetUrl, { method: 'GET', headers: { 'Accept': 'image/*' } }); const cache = caches.default; let response = await cache.match(cacheKey); if (!response) { response = await fetch(targetUrl, { method: 'GET', headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', 'Accept': 'image/*', } }); if (response.ok) { const responseToCache = response.clone(); const cacheHeaders = new Headers(responseToCache.headers); cacheHeaders.set('Cache-Control', 'public, max-age=604800'); const cachedResponse = new Response(responseToCache.body, { status: responseToCache.status, headers: cacheHeaders }); context.waitUntil(cache.put(cacheKey, cachedResponse)); } } const newHeaders = new Headers(response.headers); Object.entries(corsHeaders).forEach(([key, value]) => { newHeaders.set(key, value); }); newHeaders.set('Cache-Control', 'public, max-age=604800'); return new Response(response.body, { status: response.status, statusText: response.statusText, headers: newHeaders }); }

📖 使用说明

🎯 API 请求

  • GET /api/3/movie/popular
  • GET /api/3/movie/123
  • GET /api/3/search/movie

参数: ?api_key=YOUR_KEY&language=zh-CN

🖼️ 图片请求

  • GET /t/p/w500/PATH.jpg
  • GET /t/p/original/PATH.jpg
  • GET /t/p/w92/PATH.jpg

支持所有 TMDB 图片尺寸

🧪 API 测试工具

测试结果将显示在这里...

💡 重要提示

⚠️ 部署前必读:

1. Cloudflare Pages Functions 会自动处理以 /api/ 开头的请求

2. 将代码中的 your-project.pages.dev 替换为您实际部署的 Pages 地址

3. 在前端应用中,将所有 TMDB API 请求的域名替换为您的 Pages URL

4. 该代理完全支持 CORS,可以直接在浏览器中使用

5. 图片请求自动缓存 7 天,API 请求缓存 10 分钟以优化性能

6. 请妥善保管您的 TMDB API Key,不要在前端代码中暴露

🎯 功能特性

自动 CORS 跨域处理
智能双层缓存策略
API & 图片双重代理
OPTIONS 预检自动响应
完整错误处理机制
Cloudflare 全球 CDN 加速
高性能异步处理
零配置部署
安全头自动配置
全局错误中间件
✅ 代码已复制到剪贴板!