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

SvelteKit +server.js API如何向客户端返回图片?

问题解决:SvelteKit API返回图片并在前端显示

核心问题

你使用的是SvelteKit的+server.js路由,这类路由必须返回标准的Response对象,而非普通JSON格式对象,这就是报错Invalid response from route /api/attachment: handler should return a Response object的根本原因。

后端代码修正

修改routes/api/attachment/+server.js,将所有返回替换为Response实例,同时调整逻辑顺序(先判断附件是否存在,避免后续属性访问报错):

/** @type {import('./$types').RequestHandler} */
export async function GET({ url }) {
    const id = Number(url.searchParams.get('id'))
    try {
        const attachment = await prisma.TurnReport_Attachments.findUnique({
            where: {
                attachment_id: id
            },
        });

        // 先判断附件是否存在
        if (!attachment) {
            return new Response(JSON.stringify({ message: 'Attachment not found' }), {
                status: 404,
                headers: { 'Content-Type': 'application/json' }
            });
        }

        // 用附件二进制数据创建Response
        return new Response(attachment.data, {
            status: 200,
            headers: {
                'Content-Type': attachment.content_type,
                'Content-Length': attachment.content_length.toString(),
                // 可选:添加缓存头优化性能
                'Cache-Control': 'public, max-age=31536000'
            }
        });
    } catch (error) {
        console.error(error);
        return new Response(JSON.stringify({ message: 'Internal server error' }), {
            status: 500,
            headers: { 'Content-Type': 'application/json' }
        });
    }
}

前端代码优化

你可以简化前端逻辑,无需先fetch再转换Blob,直接让新标签页请求API地址即可:

async function getAttachment(id) {
    // 直接在新标签页打开API路由,浏览器会自动解析渲染图片
    window.open(`/api/attachment?id=${id}`, '_blank');
}

如果坚持使用fetch方式,后端修正后原有代码即可正常工作,也可添加内存泄漏优化:

async function getAttachment(id) {
    const response = await fetch(`/api/attachment?id=${id}`);
    if (!response.ok) throw new Error('获取图片失败');
    
    const blob = await response.blob();
    const urlObject = URL.createObjectURL(blob);
    const newTab = window.open(urlObject, '_blank');
    
    // 页面加载完成后释放URL对象,避免内存泄漏
    newTab?.addEventListener('load', () => {
        URL.revokeObjectURL(urlObject);
    });
}

关键说明

  • +server.js是SvelteKit的标准API路由,遵循Web规范,必须返回Response对象,与+page.server.js的返回格式不同
  • 确保attachment.data为二进制类型(如Buffer、Uint8Array),Prisma存储Bytes类型时会自动转为Buffer,可直接传入Response
  • 正确设置Content-Type头,浏览器才能识别图片类型并正常渲染

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 09:53:39