You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;
}

问题原因

  1. 序列化组未覆盖关联的Media实体:Website实体的Qrcode_image字段配置了#[Groups(['qrcode'])],但关联的Media实体没有添加对应的序列化组注解,导致Symfony序列化器无法将Media对象的属性输出到JSON响应中,最终表现为空数组/对象。
  2. 控制器中多余的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 11:05:18