[React/S3] 이미지 저장 구현 (+ CORS 에러 해결)

2024. 11. 16. 15:25·Library & Runtime/React

PWA에서 다운로드 버튼을 클릭하면 사용자의 갤러리에 이미지가 저장되도록 하는 것이 구현 목표이다.

일반적인 웹에서의 다운로드 링크로는 한계가 있었다.

 

💾 이미지 다운 구현

1. Blob 객체로 이미지 데이터 처리

현재 나는 백엔드에서 받은 이미지 url을 가지고 있는 상황이다.

이미지 url을 Blob으로 변환한다.

 

2. 패키지 설치

file-saver 라이브러리를 활용해 Blob을 png로 변환한다.

나 같은 경우는 파일명에 .png로 지정해 주어 png로 저장되지만, .jpg로 지정하면 jpg로 저장된다.

yarn add file-saver

 

3. 파일 저장 구현

const handleDownload = async () => {
  try {
    const response = await fetch(imageUrl);
    const blob = await response.blob();
    saveAs(blob, `KidWe_${Date.now()}.png`);
  } catch (error) {
    toast.error('이미지 저장 실패');
  }
};

 

🚨 에러 발생

Access to fetch at 'https://common-kidwe-image.s3.ap-northeast-2.amazonaws.com/001b5fb1-9ea7-46a7-82b6-9a0f9aa7d31f.png' from origin 'http://localhost:3030' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

 

🥁 해결 과정

const response = await fetch(imageUrl, {mode: 'no-cors'});

 

사실 이렇게 우회해 봤는데 이미지 저장이 되는 줄 알았으나 파일을 열어보니 아래처럼 떴다.. 하긴 당연히 안 되는 게 맞지

 

CORS 허용해주자!

이미지를 s3 bucket에 저장해서 쓰고 있었는데, s3에서 우리 도메인 요청을 허용해야 한다.

근데... 다 허용했는데도 안 됐다.............. 대체 왜지..?

 

캐싱할 때 CORS 헤더 누락

찾아보니 브라우저가 이미지를 캐시에 저장할 때 CORS 헤더 없이 저장하여 캐시에서 가져올 때 CORS에 의해 차단되는 것 같다. 

아래 코드처럼 imageUrl 뒤에 ?not-from-cache-please를 추가했더니 해결되었다.

const handleDownload = async () => {
    try {
      const response = await fetch(`${imageUrl}?not-from-cache-please`, {
        method: 'GET',
        mode: 'cors',
      });
      const blob = await response.blob();
      saveAs(blob, `KidWe_${Date.now()}.png`);
    } catch (error) {
      toast.error('이미지 저장 실패');
    }
  };

 


 

📝 참고글

 

[AWS SAA] S3 CORS

브라우저에서는 보안적인 이유로 cross-origin HTTP 요청들을 제한을 합니다. 그래서 cross-origin 즉, 다른 Origin 간에 요청을 하려면 서버의 동의가 필요합니다. 만약 서버가 동의한다면 브라우저에서

velog.io

 

 

이미지 가져올때 CORS 오류가 발생한다....!!!!! [AWS S3+CDN]

이미지를 가져오고 싶은데 cros 오류가 발생한다... cors는 통신때만 해주면 되는데 왜 여기서 까지 발생할까... 이유를 검색해보니 초기 이미지를 캐싱하는 단계에서는 cors 헤더를 가져가지 않고

become-a-developer.tistory.com

 

반응형

'Library & Runtime > React' 카테고리의 다른 글

[React] 자식 컴포넌트 렌더링 : 일반 함수 vs useCallback  (0) 2025.05.02
[React] 컴포넌트 생명주기 : useEffect, 마운트, 언마운트  (0) 2025.05.01
camelCase 요청 데이터를 snake_case로 변환하기  (0) 2024.11.05
snake_case 응답 데이터를 camelCase로 변환하기  (0) 2024.11.04
'Library & Runtime/React' 카테고리의 다른 글
  • [React] 자식 컴포넌트 렌더링 : 일반 함수 vs useCallback
  • [React] 컴포넌트 생명주기 : useEffect, 마운트, 언마운트
  • camelCase 요청 데이터를 snake_case로 변환하기
  • snake_case 응답 데이터를 camelCase로 변환하기
올콩
올콩
콩 심은 데 콩 난다
  • 올콩
    콩스토리
    올콩
  • 전체
    오늘
    어제
    • 분류 전체보기 (140) N
      • SSAFY (10)
      • Algorithm (67)
        • 이론 (5)
        • 백준 (BOJ) (61)
        • 프로그래머스 (1)
      • Language (9)
        • JavaScript (0)
        • TypeScript (0)
        • Java (9)
        • Python (0)
      • Library & Runtime (15) N
        • React (13) N
        • Node.js (2)
      • Framework (9)
        • 이론 (2)
        • Next.js (3)
        • Vue (4)
      • DevOps (3)
        • Git (3)
      • WEB (17)
        • HTML (9)
        • error (6)
        • etc (2)
      • Computer (5)
        • 자격증 (2)
        • tip (2)
        • etc (1)
      • CS (5)
        • Network (1)
        • Blockchain (4)
  • 블로그 메뉴

    • GitHub
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    딕셔너리
    Java
    Algorithm
    kakaomap
    SSAFY
    싸피
    소수
    파이썬
    Next.js
    티스토리챌린지
    React
    dfs
    자바
    카카오맵
    재귀
    강의
    해시
    Error
    html5
    블록체인
    우선순위큐
    백준
    렌더링최적화
    SSAFYcial
    알고리즘
    vue
    DP
    github
    오블완
    bfs
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
올콩
[React/S3] 이미지 저장 구현 (+ CORS 에러 해결)
상단으로

티스토리툴바