이미지 데이터 이슈 해결하기

·2023년 9월 28일
6

프로젝트

목록 보기
1/3
post-thumbnail

🔎 이미지 데이터 이슈 해결하기

Kream 사이트에 있는 여러 데이터들과 Kream 측에서 제공하는 이미지 주소를 함께 크롤링 작업을 했고, 사이트에서 추출한 img url을 제 프로젝트의 img src에 넣어 클라이언트단에서 이미지 보여주기를 시도했습니다. url 서치창에 이미지 url 을 입력해 이미지를 볼 수 있지만 코드단에서 img src에 주소를 넣고 보니 화면에서 엑박이 뜨는 현상을 마주했습니다.

🧮 에러 시연

이미지 주소 추출

예시 이미지 주소

https://kream-phinf.pstatic.net/MjAyMzA5MjFfOTQg/MDAxNjk1MjY2NDY5MDcw.RtV1meiGRhF18C3rW3IFID1O_q-0O5ZMGyQ4d02s0V0g.GKBtYsQ5SoYfgA4uavvKeJin7fHvJz12F9rJWJFOLcsg.JPEG/a_7c9277a0c2f649fa9727b4a94883a7c3.jpg?type=l_webp

코드

const testImg = 'Kream 예시 이미지 주소..'
   <img src={testImg} />

🚫 이미지 엑박 이슈

이처럼 Kream 이미지 주소를 src에 넣으면 이미지가 엑박이 뜨는 이슈를 직면했습니다.

네트워크 탭 에러 확인하기

이처럼 네트워크 탭을 눌러 확인을 해보니 403 에러가 나는 것을 확인할 수 있습니다.
그리고 referrer Policy 정책을 보니 strict-origin-when-cross-origin 라고 되어 있습니다. 상태 코드와 함께 referrer Policy 정책을 좀 더 자세히 알아보도록 하겠습니다.

403 에러는 뭘까요 ?

403 에러는 서버에 요청을 했지만 권한상의 문제로 거절되었다는 에러입니다. 즉, 이미지 서버측에서 다른 도메인에서 온 요청임을 확인하고 요청을 거절했다는 것입니다.

local host 🥺 : Kream 한테 요청!
Kream 😬 : Kream 이 아닌 다른 도메인이네 ? (거절)

Examples

PolicyDocumentNavigation toReferrer
no-referrer-when-downgradehttps://example.com/pagehttps://mozilla.org/https://example.com/page
strict-origin-when-cross-originhttps://example.com/pagehttps://mozilla.org/https://example.com/
no-referrerhttps://example.com/pageanywhere(no referrer)

🎉 해결 방법

1. 메타 태그 설정

<meta name="referrer" content="no-referrer" />

2. 서버 통신 요청 코드에 입력하기

 {
      headers: {
        referrerPolicy: "no-referrer",
      },
    }

3. 이미지 태그 no-referrer

<img referrerpolicy="no-referrer" src="외부 이미지 경로">

"no-referrer" 속성을 통해 현재 페이지에서 링크된 다른 웹페이지로 이동할 때 리퍼러 정보(이전 페이지 주소)를 제공하지 않도록 브라우저에 지시합니다. 다른 웹페이지로 이동할 때 리퍼러 헤더에 빈 값이 포함되어 이전 페이지의 주소가 노출되지 않습니다.

이렇게 이미지 이슈를 해결 할 수 있었지만 element 별로 정책을 주는 것도 모든 브라우저에서 되는 것은 아닙니다. 프로젝트의 완성도를 위해 더 나아가 Img 주소를 크롤링해 모으는 것에서 끝나는 것이 아닌 추출한 url 을 통해 이미지를 직접 s3에 저장 한 후 db 에 데이터를 연결에 img src로 이미지를 보여줄 수 있게 만들어야겠다고 생각했습니다.

🪣 S3를 이용해서 Img 를 새롭게 저장해보자

[ ✔️ ] AWS 아이디 생성
[ ✔️ ] IAM 생성
[ ✔️ ] Bucket 생성

S3? IAM?

S3 : (Simple Storage Service) 아마존에서 제공하는 인터넷용 스토리지 서비스.웹 등에서 사용되는 사진, 텍스트 등 여러 데이터를 손쉽게 저장 및 관리할 수 있습니다.

IAM: (Identity and Access Management) AWS 리소스들에 대한 접근을 제어할 수 있는 서비스.권한을 부여 혹은 제한하여 리소스 보관의 안정성을 높입니다.

AWS S3 생성자를 생성해 내 S3 버켓을 연결하기

const s3 = new AWS.S3({
  accessKeyId: "s3의 acessId",
  secretAccessKey: "s3의 secretKey",
  region: "ap-northeast-2",
});

URL 을 받아 이미지 S3 에 저장하는 함수 만들기


const BucketName = "나의 버켓 s3 네임";

async function uploadImageToS3(url, key) {
  const response = await axios.get(url, { responseType: "arraybuffer" });
  // ArrayBuffer 형식으로 응답 데이터 받기
 
  const params = {
    Bucket: BucketName,
    Key: key + ".jpeg", //확장자 선택
    Body: response.data,
    ContentType: response.headers["content-type"],
    ContentLength: response.headers["content-length"],
    Overwrite: true,
  };

  return new Promise((resolve, reject) => {
    s3.upload(params, (err, data) => {
      if (err) reject(err);
      else resolve(data);
    });
  });
}

파일을 업로드하기 전에 해당 파일의 내용을 버퍼로 읽어야 합니다. 크롤링을 통해 추출한 Kream 의 이미지 url 을 axios 통신을 통해 response 를 받아 이진 데이터로 변환합니다. 함수의 두번 째 인자인 key 값은 생성 될 이미지에게 부여 될 이름인데 저는 uuid 를 사용해 고유한 id값을 설정해 인자로 넣어주었습니다.

response data 결과값

<Buffer ff d8 ff e0 00 10 4a 46 49 46 00 01 01 00 00 01 00 01 00 00 ff db 00 43 00 03 02 02 03 02 02 03 03 03 03 04 03 03 04 05 08 05 05 04 04 05 0a 07 07 06 ... 59849 more bytes>

ArrayBuffer란 ?

  • 자바스크립트에서 구현된 버퍼
  • ArrayBuffer란 개발자가 지정한 메모리 크기만큼의 바이너리 데이터를 저장하는 객체

db / 클라이언트 / s3 버킷 / Node 서버와 서로 연결하는 로직 순서

1. Kream img url 을 추출한다.
2. url을 araryBuffer Type 으로 axios.get 요청을 한다.
3. 응답받은 데이터 정보들을 통해 params 를 만든다.
4. s3.upload 함수의 첫 번째 인자로 params 를 넘긴다.
5. uploadImageToS3 함수를 실행시킨 뒤 받은 응답 확인한다.

ex:)

{
  ETag: '와챠이태그',
  ServerSideEncryption: '-',
  Location: '이미지 주소..',
  key: '이미지 이름..',
  Bucket: '버켓 네임'
}

6. 응답의 Location 을 데이터에 삽입한다.

S3 bucket 🪣 에 저장된 이미지 확인해 보기

잘 저장✨ 이 된 것을 확인 할 수 있습니다! s3버킷을 만드는 과정은 이 글의 핵심이 아니기 때문에 생략했습니다.

DB에 S3에 저장되어 있는 이미지가 잘 삽입됐는지 확인해보기

이 또한 DB 에 s3 주소가 잘 저장✨ 이 된 것을 확인 할 수 있습니다!

제가 개발을 하면서 가장 중요하게 생각하는 것은 "자동화" 입니다. 로그인부터 이미지 url 추출, 추출한 이미지 데이터를 버퍼로 변환해 s3에 삽입하는 것 까지 모두 코드로 구현을 했는데요. 제 S3 버킷과 DB에 들어간 이미지 데이터만 해도 족히 500여개가 넘을 것으로 예상 됩니다. 이 수 많은 데이터를 하나하나 손수 삽입 했다면 굉장히 오래걸리고 지루한 작업이 됐겠죠 ?

코드 몇 줄로 언제든 Img 데이터를 Insert, Delete 할 수 있게 되는 것이 참 재밌다는 생각이 듭니다.

📚 레퍼런스

uploading-files-to-aws-s3-with-node-js
https://stackabuse.com/uploading-files-to-aws-s3-with-node-js/

Base64-Blob-ArrayBuffer-File-다루기-정말-이해하기-쉽게-설명
https://inpa.tistory.com/entry/JS-%F0%9F%93%9A-Base64-Blob-ArrayBuffer-File-%EB%8B%A4%EB%A3%A8%EA%B8%B0-%EC%A0%95%EB%A7%90-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-%EC%89%BD%EA%B2%8C-%EC%84%A4%EB%AA%85#%EC%9D%B4%EB%AF%B8%EC%A7%80_url%EC%9D%84_base64%EB%A1%9C_%EB%B3%80%ED%99%98%ED%95%98%EA%B8%B0

Amazon S3에 사진 업로드
https://docs.aws.amazon.com/ko_kr/sdk-for-javascript/v2/developer-guide/s3-example-photo-album-full.html

React-Ajax-Axios**
https://velog.io/@jinyoung234/React-Ajax-Axios

AWS - S3 사용하기 (버킷 만들기)
https://velog.io/@jinseoit/AWS-S3-bucket

profile
My Island

2개의 댓글

comment-user-thumbnail
2023년 10월 3일

진짜 너무 고생하셨어요!! 이런 해결방법이 있었군요! 잘보고 갑니다😊

1개의 답글