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

SvelteKit中hooks.server.ts如何读取请求体且避免报错?

在SvelteKit的hooks.server.ts中正确读取请求体的方法

当你直接调用request.body.getReader()读取流后,这个ReadableStream会被**锁定(locked: true)**且状态变为closed,后续任何尝试读取该流的操作(比如request.json())都会抛出"Body is unusable"错误——因为Fetch API的请求体流是一次性的,被读取消耗后就无法重复使用。

下面提供两种可靠的解决方案:

方案一:读取后重新构建Request对象

读取请求体内容后,基于原始请求创建新的Request实例,把读取到的内容重新作为body传入,让后续路由/中间件能正常读取请求体:

import type { Handle } from '@sveltejs/kit';

export const handle = (async ({ event, resolve }) => {
  // 仅针对有请求体的方法处理,比如POST/PUT
  if (['POST', 'PUT', 'PATCH'].includes(event.request.method)) {
    // 读取请求体文本
    const bodyText = await event.request.text();
    console.log('请求体内容:', bodyText);

    // 重新构建Request,保留原始请求的方法、头等信息
    event.request = new Request(event.request, {
      body: bodyText,
      headers: event.request.headers
    });
  }

  const response = await resolve(event);
  return response;
}) satisfies Handle;

如果需要解析JSON:

import type { Handle } from '@sveltejs/kit';

export const handle = (async ({ event, resolve }) => {
  if (['POST', 'PUT', 'PATCH'].includes(event.request.method)) {
    const bodyText = await event.request.text();
    const bodyData = JSON.parse(bodyText);
    console.log('解析后的请求体:', bodyData);

    // 重新构建Request,确保后续能再次调用json()
    event.request = new Request(event.request, {
      body: bodyText,
      headers: event.request.headers
    });
  }

  const response = await resolve(event);
  return response;
}) satisfies Handle;

方案二:克隆请求后读取

先克隆原始Request对象,读取克隆后的请求体,这样原始请求的流不会被消耗,后续依然可以正常使用:

import type { Handle } from '@sveltejs/kit';

export const handle = (async ({ event, resolve }) => {
  if (['POST', 'PUT', 'PATCH'].includes(event.request.method)) {
    // 克隆原始请求,避免消耗原请求的流
    const clonedRequest = event.request.clone();
    const bodyText = await clonedRequest.text();
    console.log('请求体内容:', bodyText);

    // 原始event.request仍可正常调用json()/text()等方法
  }

  const response = await resolve(event);
  return response;
}) satisfies Handle;

注意事项

  • 不要盲目处理所有请求:GET/DELETE等请求通常没有请求体,无需处理。
  • 若请求体是二进制数据,将text()替换为arrayBuffer(),重新构建Request时传入对应的Buffer即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 12:20:41