웹 페이지를 개발하다 보면, 사용자가 링크를 클릭했을 때 파일의 실제 내용을 화면에 보여주는 대신 "파일 다운로드" 대화 상자가 나타나도록 하고 싶은 경우가 있습니다. 이는 HTTP 헤더를 활용하면 아주 간단하게 구현할 수 있습니다.
HTTP 헤더를 이용한 다운로드 처리 원리
브라우저가 파일 내용을 출력하지 않고 다운로드하도록 유도하려면 다음 두 가지 HTTP 헤더를 설정해야 합니다.
- Content-Type: application/octet-stream — 응답 데이터가 일반 바이너리 파일임을 브라우저에 알립니다.
- Content-Disposition: attachment — 브라우저가 내용을 화면에 표시하는 대신 파일 다운로드 대화 상자를 열도록 지시합니다.
예제 코드
예를 들어, 특정 링크를 통해 FileName이라는 파일을 다운로드할 수 있게 만들려면 다음과 같이 작성합니다.
#!/usr/bin/python
# HTTP Header
print "Content-Type:application/octet-stream; name = \"FileName\"\r\n";
print "Content-Disposition: attachment; filename = \"FileName\"\r\n\n";
# Actual File Content will go here.
fo = open("foo.txt", "rb")
str = fo.read();
print str
# Close opend file
fo.close()코드 동작 설명
- 먼저
Content-Type헤더를 출력하여 응답이 바이너리 파일임을 브라우저에 알립니다. Content-Disposition헤더에attachment와filename을 지정하여 다운로드 대화 상자를 띄우고, 저장 시 기본 파일 이름을 설정합니다.foo.txt파일을 바이너리 읽기 모드(rb)로 연 후 전체 내용을 읽어 출력합니다.- 마지막으로
close()메서드로 열려 있던 파일을 닫아 리소스 누수를 방지합니다.
참고: 위 예제는 Python 2 스타일(print 문)로 작성되었습니다. Python 3 환경에서는 print() 함수 형식으로 변환하고, 바이너리 데이터를 출력할 때는 sys.stdout.buffer.write()를 사용하는 것이 좋습니다.