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
相关产品推荐
相关产品推荐

