URL 재작성 뒤 POST 본문을 다시 읽지 못하는 오류 해결

이 글의 목차 7개 항목
  • 분야: BE
  • 기술 스택: TypeScript · vinext · Vite · Web Request API

문제와 원인

vinext 요청 파이프라인은 URL을 재작성하면서 원본 Request를 새 Request의 초기값으로 전달했다. 첫 재작성 요청의 본문을 읽으면 원본도 bodyUsed=true가 돼, 같은 원본으로 두 번째 Request를 생성할 때 TypeError가 발생했다.

수정 전 코드

URL 재작성

cloned = new Request(url, request);

수정 후 코드

preserveVinextRequestBodies 변환 결과

본문이 있고 아직 소비되지 않은 Request를 먼저 clone()한 뒤 복제본을 URL 재작성에 사용한다. 원본 본문은 다음 라우트 단계에서 읽을 수 있도록 보존한다.

const requestInitSource = request.body && !request.bodyUsed
  ? request.clone()
  : request;
cloned = new Request(url, requestInitSource);

transform

빌드 플러그인은 대상 vinext 모듈에서 기존 복사식이 정확히 1개일 때만 변환한다. 0개나 2개면 내부 구현이 달라졌다는 오류로 빌드를 중단한다.

const occurrences = code.split(UNSAFE_REQUEST_COPY).length - 1;
if (occurrences !== 1) {
  throw new Error(
    `Unsupported vinext request pipeline: expected one unsafe Request copy, found ${occurrences}.`,
  );
}

검증 결과

재현 입력은 UTF-8 25 B의 POST JSON이다.

{"action":"submit","n":1}

Node.js에서 같은 25 B JSON으로 수정 전 복사식과 빌드 플러그인이 변환한 복사식을 각각 두 차례 실행했다. Cloudflare Wrangler의 로컬 Worker에서도 같은 복사식의 본문 보존 결과를 재현했다.

비교 항목수정 전수정 후
첫 재작성 요청 본문25 B, 입력과 일치25 B, 입력과 일치
첫 본문 읽기 후 원본 bodyUsedtruefalse
원본으로 두 번째 Request 생성·본문 읽기TypeError성공, 25 B와 전체 문자열 일치
플러그인 입력결과
다른 모듈 경로변환 건너뜀
대상 모듈에 기존 복사식 0개변환 거부
대상 모듈에 기존 복사식 2개변환 거부
로컬 Worker: 수정 전 본문 소비 오류와 수정 후 25 B 보존원본 보기 (새 창)

로컬 Worker: 수정 전 본문 소비 오류와 수정 후 25 B 보존

100%원본 보기 (새 창)

확대한 이미지는 상하좌우로 이동할 수 있습니다. 키보드는 이미지 영역에 초점을 두고 방향키를 사용하세요. Esc로 닫습니다.