# 跨域设置

URL: https://caijiao.org/koa/advanced/cors
Source: docs/koa/advanced/cors.md
Description: 跨域资源共享（CORS）是 Web 应用中常见的问题。本文介绍如何在 Koa 中配置跨域设置，确保前端和后端的通信不受限制。

在现代 Web 开发中，跨域请求（CORS，Cross-Origin Resource Sharing）是一个常见的问题。当浏览器从一个域名向另一个域名发起请求时，可能会遇到跨域问题。为了解决这个问题，CORS 提供了一种机制来允许跨域访问资源。本文将介绍如何在 Koa 中配置跨域设置，解决跨域问题。

## 1. 什么是 CORS？

CORS（跨域资源共享）是一种浏览器安全功能，它通过允许浏览器访问来自不同源的资源来实现跨域请求。在默认情况下，浏览器会阻止网页发起跨域请求，但服务器可以通过设置相应的 HTTP 头来允许某些跨域请求。

## 2. 在 Koa 中配置 CORS

在 [Koa](/koa/) 中，配置 CORS 最简单的方法是使用 `koa2-cors` 中间件。`koa2-cors` 是一个用于处理 CORS 请求的中间件，支持多种配置选项。

### 安装 `koa2-cors`

```bash
npm install koa2-cors
````

### 基本配置

安装完中间件后，可以在 Koa 应用中使用它来处理跨域请求。

```js
const Koa = require('koa');
const cors = require('koa2-cors');
const app = new Koa();

app.use(cors({
  origin: '*',  // 允许所有域名的跨域请求
  allowMethods: ['GET', 'POST', 'PUT', 'DELETE'],  // 允许的请求方法
  allowHeaders: ['Content-Type', 'Authorization'],  // 允许的请求头
}));

app.use(ctx => {
  ctx.body = 'Hello, world!';
});

app.listen(3000);
```

在此例中，`origin: '*'` 表示允许所有域名的跨域请求。`allowMethods` 和 `allowHeaders` 配置了允许的请求方法和请求头。

## 3. 更细粒度的 CORS 配置

在实际开发中，我们通常需要更细粒度的控制。可以根据不同的来源域、请求方法或头部设置不同的 CORS 策略。

### 只允许特定域名访问

```js
app.use(cors({
  origin: (ctx) => {
    if (ctx.request.header.origin === 'https://example.com') {
      return 'https://example.com';  // 只允许 example.com 访问
    }
    return '*';  // 其他域名不允许跨域
  },
}));
```

### 允许特定请求方法

```js
app.use(cors({
  allowMethods: ['GET', 'POST'],  // 只允许 GET 和 POST 请求
}));
```

## 4. CORS 预检请求

当浏览器发送跨域请求时，特别是使用了自定义请求头（如 `Authorization`）或请求方法（如 `PUT`）时，浏览器会先发送一个 `OPTIONS` 请求，这个请求称为“预检请求”。如果服务器响应了正确的 CORS 头，浏览器才会继续发送实际的请求。

`koa2-cors` 会自动处理 `OPTIONS` 请求，不需要手动配置。

## 5. 使用 CORS 防止恶意请求

在实际应用中，有时候我们需要防止某些恶意请求。可以通过限制 CORS 的来源域来增强安全性。

### 示例：限制来源域

```js
app.use(cors({
  origin: (ctx) => {
    const allowedOrigins = ['https://trusted.com', 'https://another-trusted.com'];
    if (allowedOrigins.includes(ctx.request.header.origin)) {
      return ctx.request.header.origin;
    }
    return 'https://default.com';  // 对不允许的域名返回默认值
  },
}));
```

## 6. CORS 与 Session、Cookie

如果跨域请求中涉及到 `Cookies` 或 `Session`，需要在 CORS 配置中添加 `credentials` 选项。

```js
app.use(cors({
  origin: 'https://example.com',  // 允许的域
  credentials: true,  // 允许发送 Cookie
}));
```

这样，浏览器在发送请求时会携带 Cookie，从而实现跨域的 Session 保持。

## 7. 总结

在 Koa 中，配置 CORS 是一个简单且灵活的过程。通过使用 `koa2-cors` 中间件，能够轻松设置跨域访问控制，确保前端和后端能够正常通信，同时避免恶意请求的干扰。通过对 CORS 配置的细粒度控制，能够实现更加安全的跨域策略，满足各种业务需求。
