# ctx 对象详解

URL: https://caijiao.org/koa/core/ctx
Source: docs/koa/core/ctx.md
Description: 详细了解 Koa 的 'ctx'（上下文）对象，包括它的各种属性和方法，帮助你更好地处理请求和响应。

在 [Koa](/koa/) 中，`ctx`（上下文）对象是每个中间件函数的核心，它包含了请求和响应的所有信息。所有的 HTTP 请求和响应都通过 `ctx` 进行处理。理解 `ctx` 对象对于开发和调试 Koa 应用至关重要。

## 1. ctx 对象的结构

Koa 的 `ctx` 对象包含了请求和响应的相关信息。它结合了 `request` 和 `response` 对象，并且提供了简洁的 API 来访问和修改它们。

### ctx 对象的结构

- `ctx.request`：封装请求信息，提供请求相关的属性和方法。
- `ctx.response`：封装响应信息，提供响应相关的属性和方法。
- `ctx.state`：可以用来存储一些应用级别的数据，常用于在中间件间传递数据。
- `ctx.app`：Koa 应用实例。

## 2. ctx.request 属性

`ctx.request` 对象封装了请求的相关信息，包含了请求头、请求方法、请求体、查询参数等。

### 常用属性和方法

- **`ctx.request.method`**：获取请求的方法（GET、POST、PUT、DELETE 等）。
- **`ctx.request.url`**：获取请求的 URL。
- **`ctx.request.header`**：获取请求的头信息。
- **`ctx.request.body`**：获取请求体的数据（通常与 POST 或 PUT 请求相关）。
- **`ctx.request.query`**：获取 URL 查询字符串的参数，返回一个对象。
- **`ctx.request.params`**：获取路由参数，返回一个对象。

### 示例

```js
app.use(async (ctx) => {
  console.log(ctx.request.method); // GET
  console.log(ctx.request.url); // /api/data
  console.log(ctx.request.query); // { id: '123' }
});
````

## 3. ctx.response 属性

`ctx.response` 对象封装了响应的相关信息，包括响应体、响应头和状态码等。开发者通过 `ctx.response` 设置响应数据。

### 常用属性和方法

- **`ctx.response.body`**：设置或获取响应体。可以是字符串、JSON 对象、Buffer 等。
- **`ctx.response.status`**：设置或获取响应的状态码（默认为 200）。
- **`ctx.response.header`**：设置响应头。
- **`ctx.response.set()`**：设置响应头。
- **`ctx.response.type`**：设置响应的类型（例如 `application/json` 或 `text/html`）。

### 示例

```js
app.use(async (ctx) => {
  ctx.response.status = 200;
  ctx.response.body = { message: 'Hello, Koa!' };
  ctx.response.set('X-Custom-Header', 'value');
});
```

## 4. ctx.state

`ctx.state` 用于在中间件之间传递应用级的数据。它并不参与请求和响应的处理，通常用来存储临时数据。

### 示例

```js
app.use(async (ctx, next) => {
  ctx.state.user = { id: 1, name: 'John' };
  await next();
});

app.use(async (ctx) => {
  console.log(ctx.state.user); // { id: 1, name: 'John' }
});
```

在上述例子中，`ctx.state` 在两个中间件之间传递数据。

## 5. ctx.app

`ctx.app` 是 Koa 应用实例的引用。它可以用于访问应用级的配置信息和功能。

### 示例

```js
app.use(async (ctx) => {
  console.log(ctx.app.env); // 输出当前环境（'development' 或 'production'）
});
```

## 6. 常用的 ctx 方法

除了属性，`ctx` 还提供了一些方法来帮助你处理请求和响应。

### `ctx.throw(status, message)`

用于抛出错误，并自动设置响应状态码和错误消息。

### 示例

```js
app.use(async (ctx) => {
  if (!ctx.request.query.id) {
    ctx.throw(400, 'Missing id parameter');
  }
});
```

### `ctx.redirect(url)`

用于重定向请求到另一个 URL。

### 示例

```js
app.use(async (ctx) => {
  ctx.redirect('https://www.example.com');
});
```

### `ctx.set(name, value)`

用于设置响应头。

### 示例

```js
app.use(async (ctx) => {
  ctx.set('X-Request-Id', '12345');
});
```

### `ctx.get(name)`

用于获取请求头中的值。

### 示例

```js
app.use(async (ctx) => {
  const userAgent = ctx.get('User-Agent');
  console.log(userAgent);
});
```

## 7. 常见的使用场景

### 设置响应体

`ctx.body` 是 Koa 中常用来设置响应体的属性，你可以根据请求的不同设置不同类型的响应体。

```js
app.use(async (ctx) => {
  if (ctx.request.url === '/json') {
    ctx.body = { message: 'Hello, JSON!' };
  } else {
    ctx.body = 'Hello, Koa!';
  }
});
```

### 路由参数解析

在使用路由参数时，`ctx.params` 提供了访问参数的便利。

```js
app.use(async (ctx) => {
  const userId = ctx.params.id;
  ctx.body = `User ID: ${userId}`;
});
```

### 使用查询字符串

Koa 提供了对查询参数的访问，`ctx.request.query` 是解析查询字符串的理想方式。

```js
app.use(async (ctx) => {
  const name = ctx.request.query.name;
  ctx.body = `Hello, ${name}`;
});
```

## 8. 总结

`ctx` 是 Koa 应用中处理请求和响应的核心对象，它封装了所有的请求信息和响应控制方法。通过理解 `ctx` 对象的属性和方法，你可以方便地处理 HTTP 请求、设置响应数据、管理应用状态等。

Koa 提供了一个非常简洁而强大的 API，通过 `ctx`，你可以轻松管理请求、响应、路由参数、查询字符串等信息，为开发高效的 Web 应用提供了极大的便利。
