문제 상황
이미지에서 주요 색상을 추출하는 기능을 구현하던 중 CORS 에러가 발생했습니다. 외부 도메인의 이미지를 Canvas API로 읽으려고 할 때 다음과 같은 에러가 발생했어요.
Access to image at 'https://external-domain.com/image.jpg' from origin 'http://localhost:3000' has been blocked by CORS policy
왜 CORS 에러가 발생할까요?
브라우저의 보안 정책 때문입니다:
이미지 표시 (
<img> 태그, CSS background-image): CORS 헤더 불필요 ✅Canvas API로 픽셀 데이터 읽기: CORS 헤더 필수 ❌
Canvas에 이미지를 그리는 것까지는 가능하지만,
getImageData()로 픽셀 정보를 읽으려면 해당 이미지 서버가 CORS 헤더를 제공해야 합니다.해결 방법: Cloudflare Workers 프록시
Cloudflare Workers를 이용해 이미지 프록시 서버를 만들어 CORS 헤더를 추가하는 방식으로 해결했습니다.
1. Cloudflare Workers 설정
Worker 코드 작성
export default { async fetch(request) { const origin = request.headers.get("Origin"); // Origin 체크 (선택사항 - 보안 강화) if (origin !== "https://localhost:3000") { return new Response("Forbidden", { status: 403 }); } const url = new URL(request.url); const targetUrl = url.searchParams.get("url"); if (!targetUrl) { return new Response("Missing 'url' parameter", { status: 400 }); } try { // 1. 대상 이미지 가져오기 const response = await fetch(targetUrl, { headers: { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36", }, }); // 2. CORS 헤더 추가 const newHeaders = new Headers(response.headers); newHeaders.set("Access-Control-Allow-Origin", "*"); newHeaders.set("Access-Control-Allow-Methods", "GET, HEAD, OPTIONS"); newHeaders.set("Access-Control-Allow-Headers", "Content-Type"); // 3. 브라우저로 응답 전달 return new Response(response.body, { status: response.status, statusText: response.statusText, headers: newHeaders, }); } catch (error) { return new Response("Error fetching image: " + error.message, { status: 500 }); } }, };
배포 확인
배포 후 Cloudflare 대시보드에서 다음을 확인할 수 있습니다:
Worker URL:
https://your-worker.workers.dev메트릭: 요청 수, 에러율, CPU 시간
버전 관리: 배포 히스토리
2. 클라이언트 코드 구현
프록시 URL 생성 함수
const IMAGE_PROXY_URL = process.env.NEXT_PUBLIC_IMAGE_PROXY_URL function getProxiedImageUrl(imageUrl: string): string { // 상대 경로나 data URL은 프록시 불필요 if (imageUrl.startsWith("/") || imageUrl.startsWith("data:")) { return imageUrl; } // 외부 도메인 이미지는 프록시 사용 return `${IMAGE_PROXY_URL}/?url=${encodeURIComponent(imageUrl)}`; }
Canvas API로 색상 추출
실제 사용 예시
// 이미지에서 색상 추출 const imageUrl = "https://external-domain.com/image.jpg"; const dominantColor = await extractDominantColor(imageUrl); console.log(dominantColor); // "indigo-500" // UI에 적용 const bgClass = `bg-${dominantColor}`;
마무리
Cloudflare Workers를 활용하면 CORS 문제를 간단하게 해결할 수 있습니다. 서버리스 환경이라 별도의 서버 관리 없이 프록시를 운영할 수 있고, 무료 티어로도 개인 프로젝트에는 충분합니다.
혹시 비슷한 문제를 겪고 계신다면 도움이 되었으면 좋겠습니다! 🎨

