thinkphp前后端分离需路由隔离、接口规范与无状态通信协同实现:前端静态资源由web服务器直托管,后端仅暴露/api/开头的json接口;路由配置须关闭强制路由、fallback非api请求至index.html、显式声明api域名与前缀;cors需中间件放行options并配置合法源与credentials;接口须显式return json()且避免输出干扰;session应弃用,改用redis验证码与jwt登录态;前端dist目录须独立部署。

ThinkPHP 前后端分离不是靠“切换模式”一键开启,而是靠路由隔离 + 接口规范 + 无状态通信三者配合。核心在于:前端静态资源(Vue/React 构建产物)由 Web 服务器直接托管,后端只暴露 /api/ 开头的 JSON 接口,两者域名/端口可完全独立。
怎么配路由让前端页面和 API 各走各的路
关键不是改默认控制器,而是把「所有非 API 请求」全部 fallback 到前端入口(如 index.html),同时明确放行 /api/ 路径给后端处理。ThinkPHP6 的 config/route.php 中应这样写:
- 关闭强制路由(
'url_route_must' => false),否则非定义路径会 404 - 用闭包或控制器统一接管前端路由:
Route::rule('[:path]', 'index/index')->ext('html');(注意加->ext('html')避免匹配到带 .json 后缀的接口) - 显式声明 API 路由前缀:
Route::domain('api', function () { Route::group('v1', function () { Route::get('user', 'api/v1/User/index'); }); });,这样https://api.your.com/v1/user就不会被前端路由吞掉 - 别用
@^/:path$这类正则通配——它会把/api/xxx也重定向到前端,导致接口 404
为什么跨域总失败?CORS 配置要分两层看
前后端分离下,前端请求后端接口时,浏览器会先发一个 OPTIONS 预检请求。ThinkPHP 默认不处理它,必须显式放行:
- 安装
think-cors:composer require think-cors - 在
app/middleware.php中注册中间件:[\think\middleware\Cors::class] - 在
config/cors.php里填实际值,别写['*']:'allow-origin' => ['http://localhost:8080', 'https://your-fe.com'] - 必须设
'allow-credentials' => true才能带 Cookie 或 Authorization 头;但此时allow-origin不能为*,否则浏览器拒绝 - 如果用 JWT,前端需在请求头加
Authorization: Bearer xxx,后端用$request->header('authorization')取值,而非依赖 Session
接口返回 JSON,但前端收不到 data 字段?检查这三点
ThinkPHP 默认返回 HTML,return json($data) 看似简单,实则受多处控制:
-
config/app.php中的'default_return_type' => 'json'只影响控制器未显式 return 时的兜底行为,不是全局开关 - 每个接口方法必须显式调用
return json($data)或return $this->success($data)(需自定义 success 方法) - 别在中间件或钩子里 echo/print_r 任何内容——哪怕一个空格,都会破坏 JSON 格式,导致前端解析失败
- 调试时用
curl -i http://your-api.com/api/v1/user看响应头是否含Content-Type: application/json,不是text/html
验证码、登录态这些依赖 Session 的功能怎么搞
前后端分离中 Session 几乎不可用——前端请求不带 Cookie,后端无法关联会话。替代方案必须放弃 Session:
- 验证码:改用 Redis 缓存 + 前端传
captcha_id参数。后端生成时存redis->setex("captcha:{$id}", 300, $code),校验时取redis->get("captcha:{$id}") - 登录态:JWT 是主流选择。用
firebase/php-jwt生成 token,前端存在 localStorage,每次请求带Authorization头;后端用中间件解析并注入用户信息到$request->user - 别试图通过
withCredentials: true强行复用 Session——SameSite=Lax 等策略会让它在多数场景下失效,且违背无状态原则
最易被忽略的是前端构建产物的部署方式:不要把 dist/ 目录丢进 ThinkPHP 的 public/ 下,而应由 Nginx/Apache 单独配置一个静态服务,指向 dist/;后端 API 则走另一个 server 块或子域名。路由、跨域、状态管理这三关卡住任何一个,分离就只是纸面概念。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











