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

Spring MVC实现含响应码与图片的Ajax响应接口技术问题咨询

解决Spring MVC接口同时返回状态码和图片的问题

你遇到的核心矛盾是既要携带业务状态码(responseCode),又要返回可被前端展示的图片二进制数据——直接返回JSON会导致图片数据被错误序列化,而设置图片类型的Content-Type又没法传递状态码。下面给你两种实用的解决方案:

方案一:用响应头传递状态码,响应体返回图片二进制

这种方式更高效,适合大图片场景,思路是把业务状态码放在自定义响应头里,响应体直接返回图片字节,同时设置正确的Content-Type。

后端代码(Spring MVC)

@GetMapping("/api/image")
// 跨域场景需要暴露自定义响应头,否则前端拿不到
@CrossOrigin(exposedHeaders = "X-Response-Code")
public ResponseEntity<byte[]> getImage() {
    try {
        // 模拟获取图片:这里替换成你的BufferedImage转byte[]逻辑
        BufferedImage image = ImageIO.read(new File("test.jpg"));
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(image, "jpeg", baos);
        byte[] imageBytes = baos.toByteArray();

        // 构建响应头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.IMAGE_JPEG);
        // 自定义头存放业务状态码
        headers.add("X-Response-Code", "SUCCESS");

        return new ResponseEntity<>(imageBytes, headers, HttpStatus.OK);
    } catch (Exception e) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.add("X-Response-Code", "FAIL");
        // 错误场景可以返回错误信息的字节数组
        return new ResponseEntity<>("{\"msg\":\"图片获取失败\"}".getBytes(StandardCharsets.UTF_8), headers, HttpStatus.INTERNAL_SERVER_ERROR);
    }
}

前端代码(XHR请求Blob)

const xhr = new XMLHttpRequest();
xhr.open('GET', '/api/image', true);
xhr.responseType = 'blob';

xhr.onload = function() {
    if (xhr.status === 200) {
        // 从响应头获取业务状态码
        const responseCode = xhr.getResponseHeader('X-Response-Code');
        if (responseCode === 'SUCCESS') {
            // 将Blob转为可展示的图片URL
            const blob = xhr.response;
            const img = document.createElement('img');
            img.src = URL.createObjectURL(blob);
            // 图片加载完成后释放URL资源
            img.onload = () => URL.revokeObjectURL(img.src);
            document.body.appendChild(img);
        } else {
            // 处理业务错误:如果是错误场景返回了JSON,可解析Blob
            const reader = new FileReader();
            reader.onload = () => {
                const errorMsg = JSON.parse(reader.result);
                console.error('图片加载失败:', errorMsg.msg);
            };
            reader.readAsText(xhr.response);
        }
    }
};

xhr.send();

方案二:将图片转为Base64字符串,放在JSON中返回

这种方式更简单,适合小图片场景,思路是把图片转成Base64字符串,作为responseMessage的data字段,整体返回JSON。

后端代码

@GetMapping("/api/image-json")
@CrossOrigin
@ResponseBody
public ResponseMessage getImageAsJson() {
    try {
        BufferedImage image = ImageIO.read(new File("test.jpg"));
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(image, "jpeg", baos);
        // 将图片字节转为Base64字符串
        String base64Image = Base64.getEncoder().encodeToString(baos.toByteArray());
        return new ResponseMessage("SUCCESS", base64Image);
    } catch (Exception e) {
        return new ResponseMessage("FAIL", null);
    }
}

// 你的ResponseMessage实体类
class ResponseMessage {
    private String responseCode;
    private String data; // 这里用String存Base64,而不是byte[]或BufferedImage

    // 构造方法、getter setter省略
}

前端代码

const xhr = new XMLHttpRequest();
xhr.open('GET', '/api/image-json', true);

xhr.onload = function() {
    if (xhr.status === 200) {
        const res = JSON.parse(xhr.responseText);
        if (res.responseCode === 'SUCCESS') {
            const img = document.createElement('img');
            // 拼接Base64格式的图片URL
            img.src = `data:image/jpeg;base64,${res.data}`;
            document.body.appendChild(img);
        } else {
            console.error('图片加载失败');
        }
    }
};

xhr.send();

为什么你之前的尝试失败?

  • 返回byte[]但Content-Type为application/json:Spring会把byte数组序列化成JSON数组(比如[255,216,255,...]),前端拿到的Blob是这个JSON字符串的二进制,并非图片原始二进制,自然无法展示。
  • 设置Content-Type为image/jpeg:此时响应体是纯图片二进制,无法同时携带JSON格式的responseMessage,前端也就拿不到业务状态码。

内容的提问来源于stack exchange,提问作者Yu Haolun

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:01:19