---
id: start.server-function
kind: recipe
product: start
framework: react
locale: zh-CN
revision: 3
sourceCheckedOn: "2026-08-03"
versionRange: "^1"
verifiedAgainst: "@tanstack/react-start@1.168.34"
contentModel: 2
packages:
  - "@tanstack/react-start"
tasks:
  - "create-server-function"
  - "server-only-code"
  - "rpc"
sourceRefs:
  - "https://tanstack.com/start/latest/docs/framework/react/guide/server-functions"
---

# 创建只在服务端执行的函数

> 使用 createServerFn 定义同源、类型安全的服务端 RPC。

## 执行契约

- **适用场景:** 应用内部需要类型安全地调用数据库、秘密或其他仅服务端能力。
- **不要使用:** 外部系统、Webhook 或跨域客户端需要调用时，改用 Server Route。
- **前置检查:** 选择 GET 或 POST，定义运行时 validator，并将底层服务端实现隔离在 server-only 文件。
- **验证结果:** 分别测试合法与非法输入，检查客户端产物不含秘密或数据库实现，并验证调用结果可序列化。
- **失败模式:** TypeScript 类型不能替代网络边界验证；若非法负载进入 handler，说明缺少或错误配置 validator。
- **安全边界:** 每个处理器都要自行鉴权和授权；不要把路由可见性当成服务端权限边界。

## 适用条件

代码需要访问数据库、秘密环境变量或文件系统，且只由当前 Start 应用调用。外部公开 API 应使用 Server Route。

## 最小实现

默认方法是 GET。有写入副作用时显式使用 POST。

File: `src/server/issues.ts`

```ts
import { createServerFn } from '@tanstack/react-start'

export const getServerTime = createServerFn().handler(async () => {
  return { now: new Date().toISOString() }
})

export const createIssue = createServerFn({ method: 'POST' }).handler(
  async () => ({ ok: true }),
)

```

## 安全边界

Server Function 是同源 RPC。没有自定义 src/start.ts 时，Start 会自动安装 CSRF 中间件；一旦自定义该文件，就要显式加入 createCsrfMiddleware。CSRF 防护不能替代认证、授权和输入校验，也不要因为调用端有类型就信任请求。

## Official sources

- https://tanstack.com/start/latest/docs/framework/react/guide/server-functions
