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

Next.js 14路由处理器返回Blob时res.blob()停滞问题排查

问题排查与解决方案

核心问题分析

你的代码里await res.blob()永久停滞,大概率是路由处理器返回的Response缺少必要的响应头信息,导致客户端无法正确识别Blob的边界,一直等待数据传输完成。

当你从https://picsum.photos/200/300获取响应后,转成Blob再包装成新Response返回时,丢失了原响应的Content-Type、Content-Length等关键头部,客户端fetch无法判断Blob是否接收完毕,从而卡住。

修复方案

方案1:直接转发外部响应(推荐)

不需要将外部响应转成Blob,直接返回原Response,这样会自动保留所有必要的头部信息:

// /test/api/route.ts
export async function GET(request: Request) {
  const res = await fetch("https://picsum.photos/200/300");
  // 直接返回外部响应,保留所有头部和流数据
  return res;
}

方案2:手动添加响应头后返回Blob

如果必须转成Blob再返回,需要从原响应中提取并设置正确的Content-Type:

// /test/api/route.ts
export async function GET(request: Request) {
  const res = await fetch("https://picsum.photos/200/300");
  const blob = await res.blob();
  // 从原响应获取Content-Type,设置到新Response中
  return new Response(blob, {
    headers: {
      "Content-Type": res.headers.get("Content-Type") || "image/jpeg",
      "Content-Length": blob.size.toString(),
    },
  });
}

客户端代码优化(可选但重要)

你的useEffect没有设置依赖数组,会导致组件每次渲染都重复调用getData,添加空依赖数组避免不必要的重复请求:

"use client";
import React, { useEffect } from "react";

const page = () => {
  useEffect(() => {
    const getData = async () => {
      const res = await fetch("/test/api");
      console.log(res);
      const blob = await res.blob();
      console.log("blob");
    };
    getData();
  }, []); // 添加空依赖数组
  return <div>page</div>;
};

export default page;

验证方法

修改路由处理器后,重新启动Next.js服务,客户端组件加载后,await res.blob()会正常执行,控制台会打印"blob"。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 04:05:17