JS fetch请求返回PHP源码而非执行后JSON输出的原因排查
问题诱因
- 服务端口混淆:5500是VS Code Live Server这类静态文件服务的默认端口,这类服务仅支持返回静态文本/HTML/JS/CSS文件,完全不具备PHP解析能力。你之前直接在浏览器访问
http://localhost:5500/main.php看到正常JSON,属于浏览器缓存了其他端口PHP服务返回结果的假象,清空浏览器缓存再访问该地址,同样会返回PHP源码。 - fetch传参格式错误:
fetch方法的第二个参数要求传入请求配置对象,直接传入Headers实例属于非法传参,浏览器无法正确构造请求,会直接向静态服务请求文件源码。 - 请求头设置错误:你发起的是无请求体的GET请求,不需要设置
Content-Type: application/json请求头,乱加该头会触发浏览器CORS预检OPTIONS请求,未做跨域处理的PHP服务无法正确响应这类请求。 - PHP代码逻辑错误:你对
PDO::query()返回的结果集调用execute()方法属于错误用法,execute()仅配合PDO::prepare()生成的预处理语句使用,query()执行时已经完成SQL运行,重复调用execute会导致查询逻辑异常。
解决方案
按顺序操作即可:
- 启动正确的PHP服务
不要用Live Server跑PHP,在项目根目录打开命令行,执行PHP内置服务命令:
启动后清空浏览器缓存,访问php -S localhost:8080http://localhost:8080/main.php,确认返回正确JSON,这一步先验证PHP服务正常。 - 修复PHP代码
首先在main.php最开头加上跨域和响应头配置,修正查询逻辑,错误场景也返回JSON格式避免前端解析失败:
修正后的main.php代码:
修正后的<?php // 跨域配置,放在所有代码最开头 header("Access-Control-Allow-Origin: *"); header("Access-Control-Allow-Methods: GET, OPTIONS"); header('Content-Type: application/json; charset=utf-8'); // 处理OPTIONS预检请求 if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { exit; } ini_set('display_errors', 1); ini_set('display_startup_errors', 1); error_reporting(E_ALL); include('functions.php'); $connection = getConn(); echo getData($connection); ?>functions.php中getData函数:function getData($connection){ $connection->query("SET NAMES 'UTF8'"); // query方法直接执行SQL,不需要额外调用execute $query = $connection->query("SELECT * FROM `table`"); if ($query) { $jobs = $query->fetchAll(PDO::FETCH_ASSOC); return json_encode($jobs, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); } else{ return json_encode([ "code" => 500, "msg" => "数据查询失败", "error" => $connection->errorInfo() ], JSON_UNESCAPED_UNICODE); } } - 修复前端fetch请求代码
去掉错误的请求头,按规范传配置对象,增加错误捕获:"use strict"; async function getData(){ try { // 注意URL端口改成PHP服务的8080,第二个参数传标准配置对象 let res = await fetch("http://localhost:8080/main.php", { method: "GET" }); if (!res.ok) throw new Error(`HTTP错误,状态码:${res.status}`); let data = await res.json(); console.log("获取到的数据:", data); } catch (err) { console.error("请求失败:", err); } } getData(); - 功能验证
前端页面可以继续用Live Server的5500端口打开,此时因为已经加了跨域配置,fetch请求会正常打到8080端口的PHP服务,拿到正确的JSON解析结果,不会再返回源码。
内容的提问来源于stack exchange,提问作者ma4stro
相关产品推荐
相关产品推荐

