php前后端分离需改三个默认行为:不渲染html、不依赖$_session传状态、不混放前端文件;必须显式设置header('content-type: application/json'),正确配置cors(含options处理、凭据支持),验证码和登录状态改用jwt或redis+唯一id替代session。

PHP 做前后端分离,不是换框架,而是改掉三个默认行为:不渲染 HTML、不靠 $_SESSION 传状态、不把前端文件塞进 public/ 目录混着跑。只要绕开这三点,Laravel、ThinkPHP 甚至原生 PHP 都能立刻跑通 API。
header('Content-Type: application/json') 必须显式写,不能省
常见现象:访问 /api/users,浏览器弹下载框,或显示乱码、空白页;Chrome 控制台报 MIME type text/html is not executable。
根本原因:PHP 脚本没声明响应类型,服务器默认返回 text/html,而 Axios、Fetch 等前端库只认 application/json。
- Laravel 中必须用
response()->json(),别用echo json_encode()+ 手动 header —— 容易漏、容易错位 - ThinkPHP 6+ 推荐配置
'default_return_type' => 'json',或控制器里直接调json() - 原生 PHP 写法:开头第一行必须是
header('Content-Type: application/json; charset=utf-8');,且前面绝不能有任何输出(包括空格、BOM、var_dump()、print_r()) - 一旦有前置输出,JSON 就会变成
{"error":"..."}前面带一堆 HTML 或空白,前端解析直接失败
跨域预检(OPTIONS)失败,光加 Origin 头没用
Vue 在 http://localhost:5173,PHP 后端在 http://localhost:8000,一发 POST 请求就卡在 OPTIONS,控制台报 Response to preflight request doesn't pass access control check。
手动写 header('Access-Control-Allow-Origin: *') 是最典型误区——它只解决一半问题,漏掉 OPTIONS 处理、凭据支持、方法白名单,上线必崩。
- ThinkPHP 推荐装官方扩展:
composer require topthink/think-cors,然后配config/cors.php,关键项不能少:'allow_credentials' => true、'allow_methods' => ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS']、'allow_headers' => ['Content-Type', 'Authorization'] - Laravel 用
fruitcake/laravel-cors,别自己拼中间件——它自动处理预检、缓存头、expose headers - 生产环境
'origin'必须写死域名,禁用*;allow_credentials设为true时,origin不能是*,否则浏览器直接拒绝 - Axios 请求若依赖 Cookie(比如还用 Session),必须加
withCredentials: true;若用 JWT,则可关掉凭据,改用Authorization: Bearer xxx
验证码校验总失败?Session 在跨域下根本不可靠
前端请求 /captcha 拿图片,后端存到 $this->session->set('captcha.key', $hash);提交表单时带验证码文本,后端查 $this->session->get('captcha.key') —— 跨域后永远返回 null。
原因很直接:浏览器跨域默认不发 Cookie,PHPSESSID 传不过去,Session 上下文就断了。
- 必须放弃 Session 绑定,改用可传递的唯一 ID:
captcha_id - 生成验证码时,后端返回 JSON:
{ "captcha_id": "abc123", "image": "data:image/png;base64,..." } - 前端把
captcha_id存进 hidden 字段或请求头,校验接口用它查 Redis:GET captcha:abc123 - 查完立刻
DEL captcha:abc123,防重放;别用文件或数据库存,Redis 是唯一靠谱选择
登录后 $_SESSION 总是空?这不是 PHP 配置问题
前端调 /login 成功,但后续请求 /user/profile 返回 401,var_dump($_SESSION) 是空数组。
这不是 session_start() 没调、也不是 php.ini 配错了,而是跨域下 Session ID 根本没传过来。
- 方案一(推荐):放弃 Session,改用 JWT。登录成功后返回 token,前端存在
localStorage,后续所有请求带Authorization: Bearer xxx - 方案二(若必须用 Session):Axios 设置
withCredentials: true,后端 CORS 配置中allow_credentials设为true,且origin不能是* - 额外注意:PHP 的
session.cookie_samesite默认是Lax,跨域请求需设为None,同时session.cookie_secure必须开启(即只走 HTTPS)——开发时可临时关掉 SameSite,但上线前必须补上
真正卡住人的从来不是“会不会写 API”,而是那些不报错、不提示、只默默失效的环节:比如 BOM 头让 JSON 解析失败,比如 CORS 配置漏掉 OPTIONS,比如验证码 ID 没传过去却还在查 Session。这些点不手动验证一遍,上线前永远心里没底。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!









