Symfony+React Axios在Apache服务器无响应问题求助
本地Symfony开发环境测试正常,部署到Apache VPS服务器后,React前端通过Axios向Symfony API发送POST请求时出现异常:数据库能正常更新,但Axios无法接收响应,useState状态更新失效。模态框功能正常,Symfony Profiler工具栏显示AJAX请求存在,但点击后提示Token "1e0b27" not found.。项目使用Symfony UX Turbo,已尝试添加Access-Control-Allow-Origin头,问题未解决。
API控制器代码
#[Route('/trades/deleteScreenshot/{id}', name: 'app_api_delete_screenshot', methods: ['POST'])] public function deleteScreenshot(Trade $trade, Request $request): JsonResponse { /** * @var User $user */ $user = $this->getUser(); // Checking if the user has access to the trading account if ($trade->getAccount()->getTrader() !== $user) { return $this->apiResponse([ 'errors' => [ 'You do not have access to this trade.' ] ], Response::HTTP_FORBIDDEN); } $tempScreenshots = $trade->getScreenshots(); $data = json_decode($request->getContent(), true); unset($tempScreenshots[$data['screenshot']]); $trade->setScreenshots($tempScreenshots); $this->entityManager->persist($trade); $this->entityManager->flush(); return $this->apiResponse([ 'message' => 'Screenshot has been deleted.', 'trade' => $this->serializer->serialize($trade, 'json', [ AbstractNormalizer::GROUPS => ['public'] ]), 'account' => $this->serializer->serialize($trade->getAccount(), 'json', [ AbstractNormalizer::GROUPS => ['public'] ]), 'user' => $this->serializer->serialize($user, 'json', [ AbstractNormalizer::GROUPS => ['public'] ]), ], Response::HTTP_OK); }
Axios请求代码
const handleDeleteScreenshot = (trade) => { if (trade !== null) { setLoading(true) axios.post(Links.deleteScreenshot(trade), data) .then(response => { const responseData = response.data.data; if (response.status === 200) { toast.success(responseData.message) updateTrade(JSON.parse(responseData.trade)) //UseState update onClose() } setLoading(false) //Loading icon in button }) .catch(error => { console.log(error) const responseData = error.response.data.data; if (responseData.errors) { responseData.errors.map(error => toast.error(error)) setErrors(responseData.errors) } else { toast.error('Unknown error occurred, please try again later.') } setLoading(false) //Loading icon in button }) } }
解决方案
修复CSRF令牌传递:Symfony默认对POST请求校验CSRF令牌,本地环境中Turbo可能自动处理令牌传递,但生产环境可能存在异常。
- 在页面meta标签中渲染CSRF令牌:
<meta name="csrf-token" content="{{ csrf_token('authenticate') }}"> - Axios请求中添加请求头携带令牌:
const csrfToken = document.querySelector('meta[name="csrf-token"]').content; axios.post(Links.deleteScreenshot(trade), data, { headers: { 'X-CSRF-Token': csrfToken } })
- 在页面meta标签中渲染CSRF令牌:
禁用Turbo对API路由的干扰:Symfony UX Turbo可能拦截AJAX请求并修改响应逻辑,可在API路由上禁用Turbo:
#[Route('/trades/deleteScreenshot/{id}', name: 'app_api_delete_screenshot', methods: ['POST'], options: ['turbo' => false])]或在Axios请求中添加头绕过Turbo:
axios.post(..., { headers: { 'Turbo-Frame': '_top' } })验证序列化逻辑:控制器中返回的
trade/account/user是序列化后的JSON字符串,若序列化存在循环引用或字段缺失,会导致前端解析失败。检查实体类的#[Groups(['public'])]标注,确保所需属性都被包含,同时在序列化配置中开启循环引用处理:$this->serializer->serialize($trade, 'json', [ AbstractNormalizer::GROUPS => ['public'], AbstractNormalizer::CIRCULAR_REFERENCE_HANDLER => function ($object) { return $object->getId(); } ])检查Apache配置:确保Apache的
.htaccess正确转发请求到Symfony前端控制器,避免请求被截断:<IfModule mod_rewrite.c> RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ index.php [QSA,L] </IfModule>查看服务器日志:检查Apache错误日志(
/var/log/apache2/error.log)和Symfony生产日志(var/log/prod.log),定位响应发送失败的具体原因,比如PHP报错、响应头异常等。
内容的提问来源于stack exchange,提问作者Jakub

