피파온라인에는 수많은 선수들이 있고 모든 선수들이 각 시즌별로 존재하며
이에 따른 각각의 이미지또한 존재한다
그러므로 특정 시즌의 선수를 보여주기 위해 이미지를 제공하는 api를 사용해야 했다
(넥슨에서 제공하는 API 테스트 페이지)
그렇지만 이대로 api를 호출하게 되면 아래의 문제가 발생한다
서버단에서 해당 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,
},
},
},
});
await axios.get(`/live/externalAssets/...)
>>
await axios.get(`https://fo4.dn.nexoncdn.co.kr/live/externalAssets/...)
이렇게 하면 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�Lbo����x�9��i~.�Ղ�=�3S��Ž�������M�C��4A��5X�_���
당연히 이런 상태로는 img에 사용할 수 없다
그러므로 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에 적용해 보면 아래와 같다
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;
};
아무 이상없이 잘 나온다