详细分析CORS 工作原理

🎯 CORS 是什么?

CORS 是一种安全机制,允许网页从不同的域(域名、协议、端口)请求资源。由于您的前端和后端部署在不同的域名上:

  • 前端:https://your-pages.pages.dev (Cloudflare Pages)
  • 后端:https://your-worker.workers.dev (Cloudflare Workers)

浏览器会阻止这种跨域请求,除非后端明确允许。

🔍 代码逐行分析

typescript 复制代码
export function handleCors(request: Request): Response | null {
  // 检查是否是 OPTIONS 请求(预检请求)
  if (request.method === 'OPTIONS') {
    // 如果是预检请求,返回一个空的响应和CORS头
    return new Response(null, {
      headers: {
        // 允许指定的前端域名进行跨域访问
        'Access-Control-Allow-Origin': 'https://your-pages.pages.dev',
        
        // 允许的HTTP方法
        'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
        
        // 允许的请求头
        'Access-Control-Allow-Headers': 'Content-Type, Authorization',
      },
    });
  }
  // 如果不是OPTIONS请求,返回null,让主流程继续处理
  return null;
}

🌐 CORS 工作原理

1. 预检请求 (OPTIONS)

当浏览器发送跨域请求时,会先发送一个 OPTIONS 请求来询问服务器是否允许实际请求。

示例流程:

复制代码
前端 (https://your-pages.pages.dev)
  → 发送 OPTIONS 预检请求到后端
  ← 后端返回 CORS 头
  → 浏览器检查通过后发送实际请求 (GET/POST)
  ← 后端返回实际数据

2. 实际请求

预检通过后,浏览器才会发送真正的请求(GET、POST等)。

🛠️ 改进建议

1. 动态允许域名(推荐)

typescript 复制代码
export function handleCors(request: Request): Response | null {
  // 允许的前端域名列表
  const allowedOrigins = [
    'https://your-pages.pages.dev',      // 生产环境
    'http://localhost:3000',             // 本地开发
    'http://localhost:5173'              // Vite 开发服务器
  ];
  
  const origin = request.headers.get('Origin');
  const allowedOrigin = allowedOrigins.includes(origin || '') ? origin : allowedOrigins[0];

  if (request.method === 'OPTIONS') {
    return new Response(null, {
      headers: {
        'Access-Control-Allow-Origin': allowedOrigin || '*',
        'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
        'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-Requested-With',
        'Access-Control-Allow-Credentials': 'true',
        'Access-Control-Max-Age': '86400', // 24小时缓存
      },
    });
  }
  return null;
}

2. 在实际响应中也添加CORS头

typescript 复制代码
// 在您的各个handler中,也需要添加CORS头
export function successResponse(data: any, message?: string): Response {
  return new Response(JSON.stringify({ success: true, data, message }), {
    headers: {
      'Content-Type': 'application/json',
      'Access-Control-Allow-Origin': 'https://your-pages.pages.dev',
      'Access-Control-Allow-Credentials': 'true',
    },
  });
}

export function errorResponse(message: string, status: number = 500): Response {
  return new Response(JSON.stringify({ success: false, error: message }), {
    status,
    headers: {
      'Content-Type': 'application/json',
      'Access-Control-Allow-Origin': 'https://your-pages.pages.dev',
      'Access-Control-Allow-Credentials': 'true',
    },
  });
}

3. 完整的使用示例

typescript 复制代码
// src/index.ts
import { handleCors, successResponse } from './utils/response';

export default {
  async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
    // 1. 首先处理CORS预检请求
    const corsResponse = handleCors(request);
    if (corsResponse) return corsResponse;

    // 2. 处理实际请求
    const url = new URL(request.url);
    
    if (url.pathname === '/api/test') {
      // 3. 在实际响应中也添加CORS头
      return successResponse({ message: 'Hello World' });
    }

    return new Response('Not found', { status: 404 });
  }
};

🔧 常见CORS头说明

头字段 说明 示例
Access-Control-Allow-Origin 允许的源 https://your-site.com
Access-Control-Allow-Methods 允许的HTTP方法 GET, POST, OPTIONS
Access-Control-Allow-Headers 允许的请求头 Content-Type, Authorization
Access-Control-Allow-Credentials 是否允许发送cookie true
Access-Control-Max-Age 预检请求缓存时间 86400 (秒)

💡 重要提示

  1. ** credentials **:如果前端需要发送cookie,需要设置 Access-Control-Allow-Credentials: true,并且 Access-Control-Allow-Origin 不能是通配符 *

  2. ** 生产环境配置 **:记得将 https://your-pages.pages.dev 替换为您实际的前端域名

  3. ** 本地开发 **:建议允许本地开发服务器的域名,方便调试

这段代码是确保您的前后端分离架构能够正常工作的关键!🚀

相关推荐
Json____12 天前
使用node-Express框架写一个学校宿舍管理系统练习项目-前后端分离
node·express·前后端分离·宿舍管理
Linux运维技术栈16 天前
域名网页加载慢怎么解决:从测速到优化的全链路性能优化实战
运维·网络·nginx·性能优化·cloudflare
一鹿有你们~17 天前
面试题-前端如何解决跨域
前端·javascript·跨域
安替-AnTi20 天前
AI急速搭建网站:Gemini、Bolt或Jules、GitHub、Cloudflare Pages实战全流程!
ai·github·cloudflare·bolt·gemini·快速搭建网站
叫我阿柒啊21 天前
从Java全栈到Vue3实战:一次真实面试的深度复盘
java·spring boot·微服务·vue3·响应式编程·前后端分离·restful api
叫我阿柒啊24 天前
从Java全栈到前端框架:一场真实的技术面试实录
java·spring boot·redis·typescript·vue3·jwt·前后端分离
Linux运维技术栈2 个月前
企业级配置:Azure 邮件与 Cloudflare 域名解析的安全验证落地详解
运维·安全·flask·azure·cloudflare
技术管理修行3 个月前
【二】主流架构模式深度对比:单体、前后端分离与微服务
微服务·云原生·架构·服务发现·前后端分离·单体架构
编程乐学4 个月前
基于Android 开发完成的购物商城App--前后端分离项目
android·android studio·springboot·前后端分离·大作业·购物商城