<p>CORS 错误需在 ThinkPHP 全局中间件中配置合法响应头,禁用 * 与 credentials:true 共存;JSON 请求需后端用 input() 或 json_decode() 解析;确保 PHP 文件为 UTF-8 无 BOM 编码;session 需前后端统一 withCredentials 和 Access-Control-Allow-Credentials 并固定 session name。</p>

Vue.js 发起请求时被浏览器拦截:CORS 错误怎么解
Vue.js 前端发请求到 ThinkPHP 后端,直接报 Cross-Origin Request Blocked 或控制台显示 OPTIONS 404,不是 Vue 写错了,是浏览器在帮你拦——它没看到后端返回合法的跨域响应头。
ThinkPHP 默认不自动加 Access-Control-Allow-Origin,得手动配。别在 Vue 里折腾代理(比如 vue.config.js 的 devServer.proxy)来绕,那只是开发阶段掩耳盗铃,上线照样崩。
- 在 ThinkPHP 的全局中间件(如
app/middleware/Cors.php)里统一写死响应头,比每个控制器里重复写更稳 - 不要用
*配Access-Control-Allow-Origin同时又设credentials: true,浏览器会直接拒掉——Vue 请求若带withCredentials: true(比如要传 cookie),后端必须指定具体域名,例如https://your-vue-app.com - 预检请求(OPTIONS)必须返回 204 或 200,且不能有 body;ThinkPHP 若没注册 OPTIONS 路由,就会 404,得补上空路由或用中间件拦截并提前响应
public function handle($request, \Closure $next)
{
$response = $next($request);
$response->header('Access-Control-Allow-Origin', 'https://your-vue-app.com');
$response->header('Access-Control-Allow-Methods', 'GET,POST,PUT,DELETE,OPTIONS');
$response->header('Access-Control-Allow-Headers', 'Authorization,Content-Type,X-Requested-With');
$response->header('Access-Control-Allow-Credentials', 'true');
return $response;
}
Vue 传参到 ThinkPHP 接收不到:input 和 param 混用踩坑
Vue 用 axios.post('/api/login', { username: 'a', password: 'b' }),ThinkPHP 控制器里写 $this->request->param('username') 却拿不到值——因为 axios 默认发的是 JSON 格式(Content-Type: application/json),而 ThinkPHP 的 param() 只解析 application/x-www-form-urlencoded 和 multipart/form-data 两类请求体。
- 要么前端改用
qs.stringify()把对象转成表单格式,并显式设置Content-Type:axios.post('/api/login', qs.stringify({ username: 'a' }), { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }) - 要么后端改用
input('username')或json_decode($this->request->getContent(), true)直接读原始 JSON 体——但注意,input()是从 raw body 里取,不经过过滤,安全性需自行校验 - ThinkPHP 6+ 的
$this->request->post()在 JSON 请求下始终为空,别试
ThinkPHP 返回 JSON,Vue 解析出错:中文乱码或 Unexpected token
Vue 收到响应后调 res.data 报错,Network 面板看响应体开头是乱码或一堆 ,大概率是 ThinkPHP 输出了 BOM 头,或者 PHP 文件本身编码不是 UTF-8 无 BOM。
立即学习“PHP免费学习笔记(深入)”;
- 检查所有 PHP 文件(尤其配置文件、中间件、控制器)是否保存为
UTF-8 无 BOM格式,编辑器右下角通常会标;Sublime / VS Code 都能一键转换 - ThinkPHP 的
Response类默认用header('Content-Type: application/json; charset=utf-8'),但如果前面有 echo、var_dump 或空格输出,JSON 就会被污染——确保控制器方法里没有意外输出 - 别在 ThinkPHP 中用
echo json_encode(...)手动输出,要用return json([...]),它会自动处理 header 和编码
登录态保持失败:Vue 带 cookie 请求,ThinkPHP 却识别不了 session
Vue 登录成功后,后续请求带了 withCredentials: true,但 ThinkPHP 后端查 $this->request->session()->get('user_id') 总是 null——session 没续上,不是 Vue 没发 cookie,是 ThinkPHP 没正确读取或写入。
- 确认 ThinkPHP 的 session 驱动已启用(
config/session.php中'type' => 'file'或 redis),且目录可写 - 前端请求必须带
withCredentials: true,后端响应头必须含Access-Control-Allow-Credentials: true和明确的Access-Control-Allow-Origin(不能是*) - ThinkPHP 默认 session name 是
PHPSESSID,但若 Nginx/Apache 有反向代理,可能被重写;可在配置里固定:'name' => 'thinkphp_session',并在 Nginx 的 proxy_set_header 中同步透传 Cookie
跨域传值这事,核心就两条:浏览器信不信你,和后端认不认你。信不信取决于响应头够不够诚恳,认不认取决于数据格式对不对得上。中间差一个字符、少一个 header、多一个 BOM,全盘皆输。











