加载中…
API 接入总览

这套 API 是什么

DouPHP 系统内置一套完整的 JSON API(约 200+ 端点),统一走 api/ 入口,最初服务于系统自带小程序,现已按「通用 API」标准补齐跨域、鉴权与错误规范,可以直接供 Vue / React 等浏览器端 SPA、移动 App、桌面客户端等任意客户端调用。

一句话理解:所有业务模块(文章、商品、订单、会员、预约、AI 助手等)都有一份对应的 JSON 接口,同一套令牌体系、同一套错误信封、同一套分页约定。

基础地址

API 统一入口为站点根目录下的 api/:

环境 基础地址(Base URL) 完整示例
生产(伪静态) https://example.com/api https://example.com/api/user/login_post
生产(兼容形态) https://example.com/api/ https://example.com/api/?route=user/login_post
本地开发 http://localhost/douphp.dou/api/ http://localhost/douphp.dou/api/?route=user/login_post

两种形态完全等价:站点根目录 .htaccess 会把 ^api/(.+)$ 重写为 api/index.php?route=$1。推荐使用伪静态路径形态;若服务器未开启重写,退化为 ?route= 查询形态即可。

路径中的 route 段即接口标识,如:

api / user / login_post
 │     │        └─ 动作(action)
 │     └─ 模块(module)
 └─ API 入口

部分接口在模块后还有子控制器层,如 api/order/cart/store(订单模块-购物车子控制器-添加)。路径末尾的纯数字自动识别为资源 ID,如 api/product/show/12 等价于 api/product/show?id=12。

统一响应信封

所有接口(含错误)一律返回如下 JSON 结构,HTTP 状态码与 code 双重表达结果:

{
  "code": "OK",
  "message": "",
  "data": { },
  "errors": { },
  "request_id": "9f2a5c8e1b3d7f40"
}
字段 类型 说明
code string 业务码。成功恒为 OK;失败为 UNAUTHORIZED、NOT_FOUND 等,详见《错误码与限流》
message string 人类可读提示文案。客户端不得依赖文案分支判断,只用于展示
data object 业务数据载体;无数据时固定为 {}(保证永远是对象,不会出现 [])
errors object 字段级校验错误集合,键=字段名、值=错误文案;无错误固定 {}
request_id string 请求追踪 ID(16 位十六进制),排查问题时提供给服务端定位日志

请求约定

  • 请求体:Content-Type: application/json 时自动解析 JSON body;传统表单(application/x-www-form-urlencoded)同样支持。POST 接口两种均可。

  • 查询参数:列表筛选、分页等走 query string,如 ?page=2&category_id=3。

  • HTTP 方法:接口遵循 REST 语义(GET 读 / POST 建 / PUT、PATCH 改 / DELETE 删)。

  • 方法伪装:部分环境(如部分网关、老客户端)不便发 PUT/DELETE,可在 POST 请求中伪装:

    • Body 携带 _method=PUT,或
    • Header 携带 X-HTTP-Method-Override: DELETE

    两者优先级:Body _method > Header。

  • 字符编码:UTF-8;响应统一 application/json; charset=utf-8。

分页约定

列表类接口统一使用 page 参数(从 1 开始),响应中返回总额与分页信息(具体字段以各模块文档为准):

GET /api/article?page=2

分页参数与页码信息在各模块的列表接口中结构一致:count(总数)、page(当前页)、page_size(每页数)、page_count(总页数);其中与小程序端兼容的接口还会附带 page_json 等预渲染字段。

鉴权一览

大多数写操作与「我的」数据需要登录,通过 Authorization 请求头携带 Bearer Token:

Authorization: Bearer <64位十六进制token>
  • 登录成功(账号密码 / 手机验证码 / 注册)后由响应 data.user.token 下发,有效期 30 天,每次调用自动续期活动时间。
  • 退出登录调 user/logout 吊销当前 token。
  • 各接口的鉴权级别(公开 / 可选 / 必须)见各模块文档的「接口一览表」。三种级别含义:
    • 公开:无须 token,匿名可调;
    • 可选:带 token 返回个性化数据,不带也能调(如文章详情里判断是否已收藏);
    • 必须:无有效 token 返回 401 UNAUTHORIZED。

详见《鉴权与会话》。

跨域(CORS)

浏览器端 SPA(Vue 等)跨域调用需要在服务端 config/security.php 中开启 CORS(默认关闭,零行为变化):

'cors' => [
    'enabled' => true,
    'allowed_origins' => ['https://your-vue-app.com', 'http://localhost:5173'],
    'credentials' => false, // 需携带 Cookie 会话(结算等)时设为 true
],
  • 命中白名单的预检请求(OPTIONS)返回 204 并带全套 Access-Control-Allow-* 头;
  • 实际请求响应自动带 Access-Control-Allow-Origin;未命中的 Origin 不返回任何 CORS 头,浏览器自行拦截;
  • 小程序 wx.request 不发 Origin 头,CORS 全链路 no-op,不受影响;
  • credentials 为 true 时不允许白名单用 *,且前端需以 withCredentials: true 发起请求。

限流

防暴力破解类接口(登录、注册、发送验证码等)带定向限流,超限返回 HTTP 429 + code: RATE_LIMITED,并附 Retry-After 响应头(单位:秒)。全表见《错误码与限流》。

快速开始(axios)

import axios from 'axios'

const api = axios.create({
  baseURL: 'https://example.com/api/',
  timeout: 15000,
  // 跨域 + Cookie 会话(结算流程)时开启:
  // withCredentials: true,
})

// 请求拦截:自动附加令牌
api.interceptors.request.use((config) => {
  const token = localStorage.getItem('api_token')
  if (token) config.headers.Authorization = `Bearer ${token}`
  return config
})

// 响应拦截:解信封 + 统一错误处理
api.interceptors.response.use(
  (res) => {
    const { code, message, data } = res.data
    if (code === 'OK') return data
    return Promise.reject(Object.assign(new Error(message), res.data))
  },
  (err) => {
    const payload = err.response && err.response.data
    if (payload && payload.code === 'UNAUTHORIZED') {
      // 令牌失效:清本地并跳登录
      localStorage.removeItem('api_token')
    }
    return Promise.reject(Object.assign(err, { payload }))
  }
)

// 示例:账号密码登录
async function login(username, password) {
  const data = await api.post('user/login_post', { username, password })
  localStorage.setItem('api_token', data.user.token)
  return data.user
}

// 示例:文章列表(第 1 页)
const list = await api.get('article', { params: { page: 1 } })

提示:URL 形态二选一时,baseURL 建议用带 /api/ 的兼容形态(https://example.com/api/),此时相对路径 user/login_post 两种服务器环境都能工作。

客户端接入检查清单

  1. 打开 CORS 白名单并登记你的前端域名(浏览器端);
  2. 实现信封解包与 401 统一跳登录;
  3. 登录后持久化 data.user.token,请求时带 Authorization: Bearer;
  4. 列表页实现 page 翻页;
  5. 429 时按 Retry-After 秒数退避重试;
  6. 异常时记录 request_id 便于服务端排查;
  7. 涉及结算(下单、优惠券、运费)的客户端若走浏览器,需开启 credentials 并使用 withCredentials(该链路依赖 Cookie 会话,详见《客户端约定与扩展字段》)。
添加日期:2026-10-06