파일을 다운로드하는 방법(HTML)

[ 이 문서는 Windows 런타임 앱을 작성하는 Windows에서 8.x 및 Windows Phone 8.x 개발자를 대상으로 합니다. Windows 10용으로 개발하는 경우에는 최신 설명서를 참조하세요.]

이 항목에서는 파일을 다운로드하는 방법을 보여 줍니다.

앱은 이 항목에서 설명하는 API를 사용하여 앱에서 웹 서비스를 조작하여 사진, 음악, 동영상 등과 같은 주요 미디어 형식을 사용하거나 공유하도록 설정할 수 있습니다.

JavaScript로 앱을 개발하는 경우 인터넷 위치에서 파일을 요청하는 두 가지 기본 옵션이 있습니다. XHR로 비동기 HTTP GET 요청을 만들어 자주 검색하는 사이트 자산과 같은 소형 파일을 다운로드할 수 있습니다. 이 함수는 JavaScript에서 비동기 동작을 사용하는 프로그래밍 패턴인 Promise에서 XMLHttpRequest 호출을 래핑합니다.

또는 작업 수명 주기 동안 앱이 여러 번 일시 중단되거나 네트워크 가용성이 변경되는 대용량 미디어(동영상 및 음악)를 다운로드할 때 일관된 환경을 제공하려면 앱에서 Background Transfer를 사용할 수 있습니다. 백그라운드 전송에 대한 자세한 내용은 백그라운드로 데이터 전송을 참조하세요.

사전 요구 사항

JavaScript 앱 만들기에 대한 일반적인 도움말은 JavaScript를 사용하여 첫 번째 Windows 런타임 앱 만들기를 참조하세요. 또한 JavaScript Promise는 이 항목에서 비동기 작업을 완료하는 데 사용됩니다. 이 프로그래밍 패턴에 대한 자세한 내용은 Promises를 사용하는 JavaScript의 비동기 프로그래밍을 참조하세요.

앱이 네트워크에 대비하도록 하려면 프로젝트 Package.appxmanifest 파일에서 접근 권한 값을 설정해야 합니다. 각 네트워크 접근 권한 값에 대한 정의는 네트워크 격리 접근 권한 값을 구성하는 방법을 참조하세요.

이 항목의 모든 백그라운드 전송 예는 백그라운드 전송 샘플(영문)을 기반으로 합니다.

XHR을 사용하여 파일 다운로드

JavaScript를 사용하여 기본 비동기 HTTP 요청을 시작하려면 XHR을 호출하고 Option 매개 변수를 사용하여 관련 요청 데이터를 제공합니다. 기본적으로 이 메서드 호출은 GET 요청이므로 Option을 통해 제공해야 하는 유일한 필수 값은 URL 및 responseType입니다. 그러나 많은 웹 서비스에는 인증이 필요하므로 XHR을 호출하여 보안 웹 서비스에서 리소스를 요청할 경우 이러한 자격 증명을 포함해야 합니다.

또한 XHR GET 작업의 경우 Option 매개 변수에서 responseType을 사용하여 응답에 필요한 콘텐츠 유형을 지정해야 합니다. 이 예에서는 .png 파일을 요청했으므로 responseType 값은 "blob"입니다. 지원되는 전체 콘텐츠 유형 목록과 콘텐츠를 요청하는 방법에 대한 예는 WinJS xhr을 사용하여 파일을 다운로드하는 방법을 참조하세요.


WinJS.xhr({ url: "https://www.microsoft.com/windows/Framework/images/win_logo.png", responseType: "blob" })
    .done(
        function (request) {
            var imageBlob = URL.createObjectURL(request.response);
            var imageTag = xhrDiv.appendChild(document.createElement("image"));
      imageTag.src = imageBlob;
     });

JavaScript에서 각 promise에는 비동기 작업의 결과를 처리하는 데 사용할 수 있는 두 개의 함수 then과 done이 있습니다. 두 함수는 모두 세 개의 매개 변수를 사용합니다. 다운로드가 완료될 때(즉, readyState가 4임) 호출되는 함수, 오류가 있을 때 호출되는 함수 및 다운로드가 진행 중일 때(즉, readyState가 2 또는 3임) 호출되는 함수입니다. done 함수만 오류가 처리되지 않을 때 예외를 throw합니다. 이 함수는 error 함수가 제공되지 않을 때 기본적으로 사용됩니다.

백그라운드 전송을 사용하여 파일 다운로드

백그라운드 전송을 사용할 경우 각 다운로드는 작업을 일시 중지, 다시 시작 및 취소하는 데 사용된 많은 컨트롤 메서드를 노출하는 DownloadOperation으로 존재합니다. 앱 이벤트(예: 일시 중단 또는 종료) 및 연결 변경은 DownloadOperation별로 자동으로 처리되며 다운로드는 앱 일시 중단 또는 일시 중지 중에도 계속되며 앱 종료 후에도 유지됩니다. 모바일 네트워크 시나리오의 경우 CostPolicy 속성을 설정하여 데이터 통신 연결 네트워크로 인터넷에 연결한 동안 앱에서 다운로드를 시작하거나 계속할지를 나타냅니다.

다음 예에서는 기본 다운로드를 만들고 초기화하는 방법과 이전 앱 세션의 지속형 작업을 열거 및 다시 시도하는 방법을 안내합니다.

Hh700370.wedge(ko-kr,WIN.10).gif백그라운드 전송 파일 다운로드 구성 및 시작

  • 다음 예에서는 URI 및 파일 이름을 나타내는 문자열을 사용하여 Uri 개체 및 요청한 파일을 포함할 StorageFile을 만들 수 있는 방법을 보여 줍니다. 이 예에서 새 파일은 미리 정의된 위치에 자동으로 배치됩니다. 또는 FileSavePicker를 사용하여 사용자가 장치에서 파일을 저장할 위치를 나타내도록 할 수 있습니다. DownloadOperation에 콜백을 다시 할당하기 위해 호출되는 load 메서드는 앱 종료 기간 동안 지속될 경우 이 섹션의 뒷 부분에서 정의하는 DownloadOp 클래스에 있습니다.

    function DownloadOp() {
        var download = null;
        var promise = null;
        var imageStream = null;
    
        this.start = function (uriString, fileName) {
            try {
                // Asynchronously create the file in the pictures folder.
                Windows.Storage.KnownFolders.picturesLibrary.createFileAsync(fileName, Windows.Storage.CreationCollisionOption.generateUniqueName).done(function (newFile) {
                    var uri = Windows.Foundation.Uri(uriString);
                    var downloader = new Windows.Networking.BackgroundTransfer.BackgroundDownloader();
    
                    // Create a new download operation.
                    download = downloader.createDownload(uri, newFile);
    
                    // Start the download and persist the promise to be able to cancel the download.
                    promise = download.startAsync().then(complete, error, progress);
                }, error);
            } catch (err) {
                displayException(err);
            }
        };
        // On application activation, reassign callbacks for a download
        // operation persisted from previous application state.
        this.load = function (loadedDownload) {
            try {
                download = loadedDownload;
                printLog("Found download: " + download.guid + " from previous application run.<br\>");
                promise = download.attachAsync().then(complete, error, progress);
            } catch (err) {
                displayException(err);
            }
        };
    }
    

    JavaScript Promise를 사용하여 정의된 비동기 메서드 호출에 유의하세요. 이전 코드 예에서 17줄을 봅니다.

    promise = download.startAsync().then(complete, error, progress);
    

    비동기 메서드 호출 뒤에 then 문이 오며, 비동기 메서드 호출에서 결과가 반환되면 호출되는, 앱에 의해 정의된 메서드를 나타냅니다. 이 프로그래밍 패턴에 대한 자세한 내용은 Promises를 사용하는 JavaScript의 비동기 프로그래밍을 참조하세요.

Hh700370.wedge(ko-kr,WIN.10).gif작업 컨트롤 메서드 추가

  • 제어 수준은 추가 DownloadOperation 메서드를 구현하여 높일 수 있습니다. 예를 들어 위의 예에 다음 코드를 추가하여 다운로드 취소 기능을 적용할 수 있습니다.

    // Cancel download.
    this.cancel = function () {
        try {
            if (promise) {
                promise.cancel();
                promise = null;
                printLog("Canceling download: " + download.guid + "<br\>");
                if (imageStream) {
                    imageStream.close();
                }
            }
            else {
                printLog("Download " + download.guid + " already canceled.<br\>");
            }
        } catch (err) {
            displayException(err);
        }
    };
    

DownloadOperation의 완료 또는 취소 시, 연결된 시스템 리소스가 해제됩니다. 이러한 이벤트가 발생하기 이전에 앱이 종료될 경우 다운로드는 일시 중지되고 백그라운드에서 지속됩니다. 다음 예에서는 지속형 다운로드를 새 앱 세션에서 다시 사용하는 방법을 보여 줍니다.

Hh700370.wedge(ko-kr,WIN.10).gif시작할 때 지속형 작업 열거

  1. 지속형 작업을 열거하는 함수를 정의하기 전에 다음과 같이 반환될 DownloadOperation 개체를 포함할 배열을 만들어야 합니다.

    var downloadOps = [];
    
  2. 그런 다음 지속형 작업을 열거하고 배열에 저장하는 함수를 정의합니다. 지속형 DownloadOperation에 대한 콜백을 다시 할당하기 위해 호출되는 load 메서드는 이 섹션의 뒷 부분에서 정의하는 DownloadOp 예에 있습니다.

    // Enumerate outstanding downloads.
    Windows.Networking.BackgroundTransfer.BackgroundDownloader.getCurrentDownloadsAsync().done(function (downloads) {
    
        for (var i = 0; i < downloads.size; i++) {
            var download = new DownloadOp();
            download.load(downloads[i]);
            downloadOps.push(download);
        }
    });
    

    참고  

    Windows Phone 스토어 앱에서는 앱이 포그라운드에 없는 경우에도 백그라운드 전송이 계속 진행됩니다. 이 시나리오에서는 앱이 실행되고 있지 않으므로 전송이 완료되어도 알림을 받지 못합니다. 앱이 다시 시작될 때 완료된 전송의 진행률을 확인하면 상태가 BackgroundTransferStatus.Running입니다. 그러나 위의 코드 예제처럼 전송에 연결하면 작업 완료 처리기가 발생되고 전송 상태가 업데이트됩니다.

요청 시간 제한

두 가지 주요 연결 시간 제한 시나리오를 고려해야 합니다.

  • 전송을 위해 새 연결을 설정할 때 5분 이내에 연결이 설정되지 않을 경우 연결 요청이 중단됩니다.

  • 연결이 설정되면 2분 이내에 응답을 받지 못한 모든 HTTP 요청 메시지가 중단됩니다.

두 경우 모두 인터넷 연결이 있고 백그라운드 전송에서 요청을 최대 세 번까지 자동으로 다시 시도한다고 가정합니다. 인터넷 연결이 검색되지 않는 경우 추가 요청은 인터넷에 연결될 때까지 대기합니다.

XHR 작업의 경우 WinJS.Promise.timeout 속성을 사용하여 특정 시간 초과 값을 정의할 수 있습니다. 이렇게 하는 방법에 대한 자세한 내용은 WinJS.xhr을 사용할 때의 시간 제한 값 설정을 참조하세요.

디버깅 지침

Microsoft Visual Studio에서 디버깅 세션을 중지하는 것은 앱을 닫는 것과 같습니다. 디버깅 중에도 앱이 이전 세션에서 지속된 다운로드를 모두 열거한 다음 다시 시작하거나 취소해야 합니다. 예를 들어 현재 디버그 세션의 이전 작업에 관심이 없는 경우 앱을 시작할 때 앱에서 열거된 지속형 다운로드 작업을 취소하도록 할 수 있습니다.

앱 매니페스트 변경 등의 Visual Studio 프로젝트 업데이트가 있으며 앱을 제거하고 다시 배포하는 경우에는 GetCurrentUploadsAsync에서 이전 앱 배포를 사용하여 만든 작업을 열거할 수 없습니다.

자세한 내용은 Windows 스토어 앱 디버깅 및 테스트를 참조하세요.

개발 중 백그라운드 전송을 사용하는 경우 활성 및 완료된 전송 작업의 내부 캐시가 동기화되지 않는 상황이 발생할 수 있습니다. 이 경우 새 전송 작업을 시작하거나 기존 작업 및 BackgroundTransferGroup 개체를 조작하지 못할 수 있습니다. 기존 작업을 조작할 때 크래시가 트리거되는 경우도 있습니다. TransferBehavior 속성이 Parallel로 설정된 경우 이러한 결과가 발생할 수 있습니다. 이 문제는 개발 중 특정 시나리오에서만 발생하며 앱의 최종 사용자에게는 해당하지 않습니다.

Visual Studio를 사용한 네 가지 시나리오에서 이 문제가 발생할 수 있습니다.

  • 기존 프로젝트와 앱 이름은 같지만 다른 언어(예: C++에서 C#으로 변경)로 새 프로젝트를 만듭니다.
  • 기존 프로젝트에서 대상 아키텍처를 변경합니다(예: x86에서 x64로 변경).
  • 기존 프로젝트에서 문화권을 변경합니다(예: 중립에서 en-US로 변경).
  • 기존 프로젝트의 패키지 매니페스트에서 접근 권한 값을 추가하거나 제거합니다(예: 엔터프라이즈 인증 추가).

접근 권한 값을 추가하거나 제거하는 매니페스트 업데이트를 비롯한 정기 앱 서비스는 앱의 최종 사용자 배포에서 이 문제를 트리거하지 않습니다.

이 문제를 해결하려면 앱의 모든 버전을 완전히 제거하고 새로운 언어, 아키텍처, 문화권 또는 접근 권한 값으로 다시 배포합니다. 시작 화면이나 PowerShell 및 Remove-AppxPackage cmdlet을 사용하여 이 작업을 수행할 수 있습니다.

요약 및 다음 단계

이 항목에서는 JavaScript에서 Background Transfer API를 사용하여 파일을 다운로드하는 방법을 검토했습니다. 두 방법의 차이점을 검토하고 실제 적용이 파일 다운로드의 크기와 빈도에 따라 어떻게 달라지는지를 강조했습니다.

또한 XHR 및 백그라운드 전송을 사용하여 파일을 업로드할 수 있습니다. 핵심 개념과 예제에 대한 자세한 내용은 파일을 업로드하는 방법을 참조하세요.

관련 항목

기타

promises를 사용한 JavaScript의 비동기 프로그래밍

JavaScript를 사용하여 첫 Windows 런타임 앱 만들기

네트워크 접근 권한 값을 구성하는 방법

WinJS xhr을 사용하여 파일을 다운로드하는 방법

파일을 업로드하는 방법

참조

HttpClient

Windows.Networking.BackgroundTransfer

WinJS.XHR

샘플

백그라운드 전송 샘플

HttpClient 샘플