Axios+Symfony:提交后在响应中获取图片路径
问题描述
使用Axios配合Symfony后端上传媒体文件后,页面刷新能正常显示新上传的图片,但API响应中的Qrcode_image字段是空数组,无法获取图片路径来实时更新页面DOM。
相关代码
前端JS代码
UpdateQrcodeImage(){ $("#website-qrcode-image-form").on("submit", function(event, datas) { event.preventDefault(); const file = $('#website-qrcode-image')[0].files[0]; const website_id = $("#website-id").attr('data-value'); let fDatas = new FormData(); fDatas.append('website-qrcodeimage', file); fDatas.append('website-id', website_id); const sendPostRequest = async () => { try { const resp = await axios.post(`/api/website/${website_id}/qrcode_image`, fDatas, { headers: { 'Content-Type': 'multipart/form-data' } }); console.log(resp.data); } catch (err) { console.error(err); } }; sendPostRequest(); }); }
Symfony控制器代码
// src/Controller/Api/ApiWebsiteController.php #[Route('/api/website/{id}/qrcode_image', name: 'api.website.qrcode_image', methods: ['POST', 'GET'])] public function website_qrcode_image(?Website $website, Request $request): JsonResponse { $data = json_decode($request->getContent(), true); $file = $request->files->get('website-qrcodeimage'); $media = new Media(); $media->setMediaFile($file); $this->em->persist($media); $website->setQrcodeImage($media); $this->em->persist($website); $this->em->flush(); return $this->json($website, 200, ['Content-Type' => "application/json"], ['groups' => ['qrcode']]); }
Website实体代码
// src/Entity/Website.php #[Groups(['qrcode'])] #[ORM\OneToOne(cascade: ['persist', 'remove'])] private ?Media $Qrcode_image = null; [...] public function getQrcodeImage(): ?Media { return $this->Qrcode_image; } public function setQrcodeImage(?Media $Qrcode_image): self { $this->Qrcode_image = $Qrcode_image; return $this; }
问题原因
- 序列化组未覆盖关联的Media实体:Website实体的
Qrcode_image字段配置了#[Groups(['qrcode'])],但关联的Media实体没有添加对应的序列化组注解,导致Symfony序列化器无法将Media对象的属性输出到JSON响应中,最终表现为空数组/对象。 - 控制器中多余的
json_decode调用:由于请求是multipart/form-data格式,解析请求内容为JSON的操作无效,不过这不会影响文件上传功能。
解决方法
1. 为Media实体添加序列化组
给Media实体中存储图片路径的属性(以及对应的getter方法)添加#[Groups(['qrcode'])]注解,确保序列化器能输出这些字段:
// src/Entity/Media.php use Symfony\Component\Serializer\Annotation\Groups; class Media { // 假设存储文件路径的属性为mediaPath #[Groups(['qrcode'])] private ?string $mediaPath = null; // 如果需要返回可直接访问的URL,可添加getWebPath方法并加注解 #[Groups(['qrcode'])] public function getWebPath(): ?string { // 根据实际上传目录返回完整URL return '/uploads/media/' . $this->mediaPath; } // 对应的getter方法也要加注解(如果属性没加的话) #[Groups(['qrcode'])] public function getMediaPath(): ?string { return $this->mediaPath; } // 其他属性和方法... }
2. 优化控制器代码
移除无用的JSON解析代码,同时增加文件存在性校验:
// src/Controller/Api/ApiWebsiteController.php #[Route('/api/website/{id}/qrcode_image', name: 'api.website.qrcode_image', methods: ['POST', 'GET'])] public function website_qrcode_image(?Website $website, Request $request, EntityManagerInterface $em): JsonResponse { $file = $request->files->get('website-qrcodeimage'); if (!$file) { return $this->json(['error' => '未上传文件'], 400); } $media = new Media(); $media->setMediaFile($file); $em->persist($media); $website->setQrcodeImage($media); $em->persist($website); $em->flush(); return $this->json($website, 200, [], ['groups' => ['qrcode']]); }
3. 前端更新DOM
现在API响应会包含Media实体的路径信息,前端可以直接获取并更新页面元素:
UpdateQrcodeImage(){ $("#website-qrcode-image-form").on("submit", function(event) { event.preventDefault(); const file = $('#website-qrcode-image')[0].files[0]; const website_id = $("#website-id").attr('data-value'); let fDatas = new FormData(); fDatas.append('website-qrcodeimage', file); fDatas.append('website-id', website_id); const sendPostRequest = async () => { try { const resp = await axios.post(`/api/website/${website_id}/qrcode_image`, fDatas, { headers: { 'Content-Type': 'multipart/form-data' } }); // 获取图片路径并更新预览 const imageUrl = resp.data.Qrcode_image.webPath; // 或者resp.data.Qrcode_image.mediaPath $('#qrcode-preview').attr('src', imageUrl); } catch (err) { console.error(err); } }; sendPostRequest(); }); }
内容的提问来源于stack exchange,提问作者Simon Mo
相关产品推荐
相关产品推荐

