Safari에서 ReadableStream을 fetch에 사용할 때의 문제와 해결 방법

궁금하면 500원·2024년 8월 25일
0

미생의 개발 이야기

목록 보기
13/58

 if(isFetchStream === undefined){
        if (typeof ReadableStream === 'undefined') isFetchStream = false;
        const testStream = new ReadableStream({
          start(controller) {
            controller.enqueue(new Uint8Array([1, 2, 3]));
            controller.close();
          }
        });
        try{
          await fetch('', { method: 'POST', body: testStream, duplex: 'half' })
        }catch(e){
          isFetchStream = e.message !== 'ReadableStream uploading is not supported';
        }
      }

문제의 발단

Safari에서는 ReadableStream을 지원하지만, fetch API의 request.body로 사용할 수 없습니다.
즉, fetch 호출 시 ReadableStream을 request.body에 전달하면 오류가 발생합니다.
이는 Safari가 fetch API에서 ReadableStream을
반이중 통신(duplex: 'half')의 body로 사용하는 것을 지원하지 않기 때문입니다.

문제 발생 과정

  • 호환성 문제
    ReadableStream을 fetch의 body로 사용하는 것이 Safari에서는 지원되지 않습니다.
    이는 Safari의 fetch 구현이 ReadableStream의 사용을 제한하기 때문입니다.

  • 에러 처리
    위 코드에서 try-catch 블록을 통해 에러를 감지하려고 시도합니다.
    그러나, ReadableStream이 지원되지 않는다는 메시지를 직접적으로 확인하는 것은 불가능합니다. 대신, fetch 호출이 실패할 때 발생하는 에러를 기반으로 이를 간접적으로 감지합니다.
    이는 매우 제한적이며, fetch 요청이 실패할 경우에만 문제를 감지할 수 있습니다.

  • 문제의 복잡성

fetch 호출 시 발생하는 에러는 DomException으로 반환되며,
이는 에러 타입을 명확히 식별할 수 없습니다.

따라서, 에러 메시지에 기반하여 문제를 추측해야 하며,
이는 매우 불안정하고 오류가 발생할 수 있는 접근 방식입니다.

감지 로직 개선

현재 접근 방식의 문제점

  • 비효율성
    현재 감지 로직은 실제 네트워크 요청을 시도하여 ReadableStream의 지원 여부를 판단합니다. 이는 불필요한 네트워크 요청을 발생시키며, 성능에 영향을 줄 수 있습니다.
  • 불확실성
    에러 메시지에 기반한 판별은 신뢰성이 낮습니다.
    다양한 브라우저 환경에서 발생할 수 있는 예외 상황을 정확히 구별하기 어렵습니다.

개선방안

브라우저 특성에 따른 유연한 대응 방법

  • 브라우저 기능 감지
    ReadableStream의 지원 여부를 확인할 때, 먼저 브라우저의 기능을 검사합니다.
    예를 들어, typeof ReadableStream !== 'undefined'로 기본 지원 여부를 확인한 후, 보다 세부적인 브라우저 호환성 검사를 수행합니다.

  • Polyfill 사용
    Safari와 같은 브라우저에서 ReadableStream의 기능을 제공하기 위해 polyfill을 사용할 수 있습니다. 이는 브라우저가 특정 기능을 지원하지 않을 때 대체 기능을 제공할 수 있습니다.

보다 신뢰할 수 있는 에러 메시지 처리

  • 정확한 에러 핸들링
    fetch 호출 시 발생할 수 있는 에러를 보다 정확하게 처리하기 위해,
    에러 객체의 상세 정보를 분석합니다.
    DomException의 name 속성 또는 다른 프로퍼티를 활용하여 에러의 원인을 명확히 구분할 수 있도록 합니다.

  • Fallback 전략
    ReadableStream을 사용하는 대신 다른 방법을 사용하여 fetch API의 body를 설정할 수 있는 대안을 제공합니다.
    예를 들어, 문자열이나 FormData를 사용하는 방법이 있을 수 있습니다.

브라우저 호환성 테이블

  • 업데이트된 정보 반영
    최신 브라우저 버전에서의 호환성 정보를 제공하는 테이블이나 문서를 작성하여,
    독자들이 현재의 브라우저 환경에 맞는 해결책을 쉽게 찾을 수 있도록 합니다.

[참조]
자바스크립트에서 데이터 스트림 읽기 (ReadableStream)

profile
꾸준히, 의미있는 사이드 프로젝트 경험과 문제해결 과정을 기록하기 위한 공간입니다.

0개의 댓글