브라우저가 파일을 다운로드하도록 강제(HTML 및 서버 측)

사용자가 파일에 대한 일반 HTML 링크를 클릭하면:

<a href="path/to/file.ext">


브라우저는 일반적으로 파일 다운로드 대화 상자를 여는 대신 파일을 직접(인라인) 열려고 시도합니다.

HTML5download 속성을 사용하여 최신 브라우저에 대신 다운로드 대화 상자를 열도록 지시할 수 있습니다.

<a href="path/to/file.ext" download>


다운로드 대화 상자에서 사용자에게 표시될 제안 파일 이름을 지정할 수도 있습니다.

<a href="path/to/file.ext" download="myfile.ext">


확장자 없이 파일 이름만 지정하면 일반적으로 원래 파일 이름에서 확장자가 유추됩니다(이 예제는 여전히 대부분의 브라우저에서 "myfile.ext"를 제안함).

<a href="path/to/file.ext" download="myfile">


제한 사항 및 해결 방법



요즘에는 download 속성이 모든 주요 브라우저에서 지원되지만 중요한 제한이 있습니다. 이 속성은 동일한 출처 URL(프로토콜, 포트 및 호스트가 일치해야 함)과 blob:data: 스키마에서만 작동합니다. .
download 특성 외에도 클라이언트 쪽에서 이 동작을 강제로 수행할 수 있는 다른 방법이 많지 않지만 서버 쪽에서는 할 수 있습니다.

HTTP 응답에 Content-Disposition 헤더를 포함하면 download 속성과 유사한 효과가 있습니다(단, 이 제한 없음).

Content-Disposition: attachment; filename=file.ext


또한 Content-type 헤더와 실제 파일 내용을 보내야 합니다.

PHP에서는 다음과 같이 표시됩니다.

header('Content-Disposition: attachment; filename="downloaded.pdf"');
header('Content-type: application/pdf');
readfile('test.pdf');


그러나 성능 오버헤드를 피하기 위해 앱 수준이 아닌 웹 서버 수준에서 수행하는 것이 좋습니다.

nginx


nginx의 경우 다음과 같이 간단할 수 있습니다.

add_header Content-Disposition 'attachment; filename="file.ext"';


참고: nginx는 일반적으로 올바른Content-type 헤더를 자동으로 전송하지만 필요한 경우 재정의할 수 있습니다.

add_header Content-Type 'application/pdf'


보다 일반적인 경우 파일 이름 없이 일반적인 application/octet-stream 헤더와 Content-Disposition를 보낼 수 있습니다.

location /myloc {
        if ($request_filename ~* ^.*?\.(pdf|zip|docx)$) {
            add_header Content-Disposition attachment;
            add_header Content-Type application/octet-stream;
        }
    }


다운로드 속성과 Content-Disposition 헤더의 조합



다운로드 속성과 Content-Disposition 헤더가 모두 존재하고 둘 다 파일 이름을 정의하는 경우 헤더에 정의된 파일 이름이 우선합니다.
Content-Disposition: inline 헤더(페이지의 일부로 콘텐츠inline를 표시하도록 브라우저에 지시함)의 경우 다운로드 속성이 우선 순위를 갖습니다(동일 출처 URL의 경우).



참고: 이것은 BetterWays.dev Wiki의 페이지 스냅샷입니다. 최신(더 나은 형식) 버전은 betterways.dev/forcing-a-browser-to-download-a-file 에서 찾을 수 있습니다.

좋은 웹페이지 즐겨찾기