[FIFAPulse] 개발기록 - blob객체로 이미지 가져오기 , 프록시 설정하기

조민호·2023년 4월 27일
0

문제 상황


피파온라인에는 수많은 선수들이 있고 모든 선수들이 각 시즌별로 존재하며

이에 따른 각각의 이미지또한 존재한다

그러므로 특정 시즌의 선수를 보여주기 위해 이미지를 제공하는 api를 사용해야 했다


(넥슨에서 제공하는 API 테스트 페이지)

그렇지만 이대로 api를 호출하게 되면 아래의 문제가 발생한다

  • CORS에러
  • 이미지 반환값이 광징히 이상함


CORS 에러 해결하기


서버단에서 해당 api를 요청하면 CORS 에러 없이 받아 올 수 있지만

브라우저에서 직접 요청하면 CORS 에러가 발생하게 된다

브라우저에서 직접 요청하면 키를 아무리 .env 파일에 숨겼다 해도

사용자가 console.log(key) 를 통해 바로 알 수 있으므로

넥슨에서 브라우저에서 직접 요청하는 경우를 막아두었다고 한다



그러므로 어쩔 수 없이 프록시 서버를 사용해야 했다

CRA의 경우, package.json에 proxy 키값을 추가하면 되지만

vite환경에서는 조금 다르다

예를 들어 , 실제 api를 보내는 url이

https://fo4.dn.nexoncdn.co.kr/live/externalAssets/common/playersAction/p280177003.png

이렇다면 package.json 대신 vite.config.ts파일에 아래와 같이 프록시를 설정한다

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import envCompatible from 'vite-plugin-env-compatible';

// https://vitejs.dev/config/
export default defineConfig({
  envPrefix: 'REACT_APP_',
  plugins: [react(), envCompatible as any],
  server: {
    port: 3000,
    proxy: { // 프록시 설정
      '/live': {
        target: 'https://fo4.dn.nexoncdn.co.kr/',
        changeOrigin: true,
        secure: false,
      },
    },
  },
});
  • /live 로 시작하는 모든 요청에 대해 ‘https://fo4.dn.nexoncdn.co.kr/’로 프록시 하게 된다 즉, 아래와 같이 변환되는 것이다
    await axios.get(`/live/externalAssets/...)
    >>
    await axios.get(`https://fo4.dn.nexoncdn.co.kr/live/externalAssets/...)
  • changeOrigintrue로 설정하면 원본 호스트 헤더를 변경하고
  • securefalse로 설정하면 인증서가 유효하지 않은 경우에도 요청을 전송하게 된다

이렇게 하면 Vite 개발 서버가 프록시 설정에 따라 자동으로 요청을 중계 하게 된다




이미지 반환값 에러 해결하기

프록시를 사용해서 요청은 제대로 되지만 이미지를 요청한 반환값에서 문제가 발생했다

일반적인 방법처럼 프로미스 반환객체의 data프로퍼티로 받아왔을 경우

반환값이 아래와 같이 괴상한 형태로 받아와진다

R�����.��!@ !�@B������v�]H� 	�~{���{�y�sϹә�M��|���o��]Z?���Fsp8�+M
t�����/��u7��Z� �s���ij����7��i��bw]K|S-��@��D���9;���Y#��^2g�]��=]�����������i�����M��X!5��*S:�c0�8	9�_Q�L󻑒bo����x�9��i~.�Ղ�=3S��Ž�������MC��4A��5X�_���

당연히 이런 상태로는 img에 사용할 수 없다

그러므로 blob객체를 사용하기로 했다

blob 객체란?

blob 객체는 이진 데이터를 나타내며, 텍스트, 이미지, 오디오, 비디오 등 다양한 형식을 지원한다

이 객체는 일반적으로 파일 업로드, 이미지 프로세싱, 미디어 처리 등에서 사용된다

URL.createObjectURL() 메소드는 Blob 객체나 File 객체를 사용하여

생성한 URL을 반환한다

이 URL은 브라우저에서 해당 객체의 데이터를 참조할 수 있는 고유한 주소를 제공하며,

이 주소를 사용하여 웹 페이지의 이미지, 다운로드 링크 등에 접근할 수 있게 된다

그리고 생성된 URL은 URL.revokeObjectURL() 메소드를 호출할 때까지

유효하다

아래는 간단한 사용 예시이다

// Blob 생성자를 사용해서 data 변숭 텍스트 파일의 blob 객체를 저장
const data = new Blob(["blablabla"], { type: "text/plain" });

// Blob 객체에 대한 URL 생성
const url = URL.createObjectURL(data);

// 생성된 URL을 사용하여 웹 페이지의 다운로드 링크 설정
const downloadLink = document.createElement("a");
downloadLink.href = url;
downloadLink.download = "example.txt";
document.body.appendChild(downloadLink);

// 필요한 작업 완료 후 URL 해제
URL.revokeObjectURL(url);


위의 개념을 바탕으로 실제 이미지 api에 적용해 보면 아래와 같다

  • axios에서 기본적으로 responseType을 지원하므로 blob객체 형태로 반환받고
  • 받은 blob 데이터를 URL.createObjectURL()을 사용하여 URL로 변환해서 img의 src로 사용해서 해결했다
getActionImg = async (spid: number): Promise<String> => {
    const result = await axios.get(`live/externalAssets/common/playersAction/p${spid}.png`, {
      headers: {
        Authorization: import.meta.env.REACT_APP_API_KEY_FIFA,
      },
      responseType: 'blob', // blob객체로 받아옴
    });

    const imgUrl = URL.createObjectURL(result.data); // url 변환
    return imgUrl;
  };

아무 이상없이 잘 나온다

profile
웰시코기발바닥

0개의 댓글