다운로드 제어#

dl 파라미터를 사용하여 이미지의 다운로드 동작을 제어할 수 있습니다. 브라우저에서 이미지를 표시할지 다운로드할지 선택할 수 있습니다.

사용법#

파라미터동작설명
(파라미터 없음)inline

브라우저에서 이미지 표시 (기본 동작)

transform=dlattachment

원본 파일명으로 다운로드

transform=dl:custom-nameattachment

지정한 파일명으로 다운로드 (확장자는 변환된 포맷에 맞게 자동 조정)

예시#

브라우저에서 표시 (기본 동작)

https://cdn.snapkit.studio/org/project/image.jpg

원본 파일명으로 다운로드

https://cdn.snapkit.studio/org/project/image.jpg?transform=dl

지정한 파일명으로 다운로드

https://cdn.snapkit.studio/org/project/image.jpg?transform=dl:my-photo

확장자는 변환된 포맷에 맞게 자동으로 조정됩니다. 예를 들어, WebP로 변환된 이미지는 my-photo.webp로 다운로드됩니다.

변환과 함께 사용

https://cdn.snapkit.studio/org/project/image.jpg?transform=w:800,format:webp,dl:optimized-image

이 예시는 이미지를 800px 너비로 크기 조정하고, WebP 포맷으로 변환한 후, optimized-image.webp로 다운로드합니다.

보안 및 표준 준수#

  • 경로 순회 방지: .. 및 경로 구분자 자동 제거
  • XSS 방지: 위험한 문자(<>:"|?* 및 제어 문자) 필터링
  • 파일명 길이 제한: 최대 255자
  • RFC 5987/6266 준수: 국제 문자(한글, 일본어 등) 안전하게 처리
  • UTF-8 인코딩: 모든 브라우저에서 올바른 파일명 표시 보장

JavaScript/TypeScript 예시#

// 다운로드 URL 생성
const createDownloadUrl = (imageUrl: string, filename?: string) => {
  const url = new URL(imageUrl);
  const existingTransform = url.searchParams.get('transform') || '';
  const dlParam = filename ? `dl:${filename}` : 'dl';
 
  // 기존 변환에 추가 또는 새로 생성
  const newTransform = existingTransform
    ? `${existingTransform},${dlParam}`
    : dlParam;
 
  url.searchParams.set('transform', newTransform);
  return url.toString();
};
 
// 사용 예시
const imageUrl = 'https://cdn.snapkit.studio/org/project/image.jpg';
 
// 원본 파일명으로 다운로드
const downloadOriginal = createDownloadUrl(imageUrl);
// → https://cdn.snapkit.studio/org/project/image.jpg?transform=dl
 
// 지정한 파일명으로 다운로드
const downloadCustom = createDownloadUrl(imageUrl, 'my-photo');
// → https://cdn.snapkit.studio/org/project/image.jpg?transform=dl:my-photo
 
// 변환과 함께 사용
const imageWithTransform = 'https://cdn.snapkit.studio/org/project/image.jpg?transform=w:800,format:webp';
const downloadTransformed = createDownloadUrl(imageWithTransform, 'optimized');
// → https://cdn.snapkit.studio/org/project/image.jpg?transform=w:800,format:webp,dl:optimized

다운로드 방식 비교: <a download> vs 서버 측 제어#

이미지 다운로드를 제어하는 두 가지 주요 방법:

  1. 클라이언트 측: HTML <a download> 속성
  2. 서버 측: Content-Disposition 헤더 (Snapkit의 dl 파라미터)

각 방식은 서로 다른 상황에 필요하며, 때로는 함께 사용됩니다.

기능 비교#

기능<a download>dl 파라미터 (서버 측)
적용 범위HTML 링크 클릭만모든 HTTP 요청
CORS 제한❌ 크로스 오리진에서 차단✅ 크로스 오리진 작동
JavaScript fetch❌ 적용 불가✅ 작동
직접 URL 접근❌ 브라우저에 표시✅ 다운로드
모바일 앱❌ 사용 불가✅ 사용 가능
API 요청❌ 사용 불가✅ 사용 가능

<a download>가 적절한 경우#

같은 도메인에서 간단한 다운로드

<!-- ✅ 같은 출처 리소스에 잘 작동 -->
<a href="/uploads/document.pdf" download="my-document.pdf">
  문서 다운로드
</a>

dl 파라미터 (서버 측)가 필요한 경우#

1. CDN/크로스 오리진 다운로드 (필수)

// ❌ <a download>로 CORS 차단
<a href="https://cdn.snapkit.studio/org/image.jpg" download="my-photo.jpg">
  다운로드 (작동 안 함 - 크로스 오리진)
</a>
 
// ✅ 서버 측 dl 파라미터 필요
<a href="https://cdn.snapkit.studio/org/image.jpg?transform=dl:my-photo">
  다운로드 (올바르게 작동)
</a>

2. JavaScript fetch/API 요청

// ✅ fetch로 다운로드 처리
const response = await fetch(
  'https://cdn.snapkit.studio/org/image.jpg?transform=dl:photo'
);
const blob = await response.blob();
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.click();

권장사항#

Snapkit 사용 시:

  • CDN이 다른 도메인에 있으므로 dl 파라미터 사용
  • <a download>는 보조적으로 사용 가능하지만 크로스 오리진에서는 작동하지 않음
  • API 통합 또는 fetch 사용 시 dl 파라미터 필수

두 방식 결합 예시:

<!-- 서버 측 제어 + 클라이언트 측 파일명 힌트 -->
<a
  href="https://cdn.snapkit.studio/org/image.jpg?transform=dl:photo"
  download="my-custom-photo.jpg"
>
  다운로드
</a>

서버의 Content-Disposition 헤더가 우선하며, download 속성은 폴백으로 작동합니다.

다음 단계#