Language: HTML | XAML

如何上傳檔案 (HTML)

Applies to Windows and Windows Phone

這個主題將說明如何將資料或檔案從裝置上傳到網際網路。

應用程式可以使用本主題討論的 API,讓這些應用程式能夠與 Web 服務互動,以使用或分享普遍使用的媒體格式,如相片、音樂及影片。

對於大量、資料流方式或多部分傳輸 (視訊、音樂以及大型影像),其操作週期可能跨越多個應用程式暫停和 (或) 網路可用性變更,您的應用程式可以使用 Background Transfer

如需背景傳輸的高階資訊,請參閱在背景傳輸資料

先決條件

如需建立 JavaScript Windows 市集應用程式的一般協助,請參閱使用 JavaScript 建立您的第一個 Windows 執行階段應用程式。另外,這個主題中使用 JavaScript Promise 來完成非同步操作。如需這種程式設計模式的詳細資訊,請參閱使用 Promise 在 JavaScript 的非同步程式設計

若要確保應用程式的網路可正常運作,您必須在專案 Package.appxmanifest 檔案中設定功能。 如需每個網路功能的定義,請參閱如何設定網路隔離功能

下列背景傳輸範例使用 JavaScript,並且使用背景傳輸範例做為依據。

背景傳輸上傳作業

使用背景傳輸時,上傳以 UploadOperation 的方式存在,可公開用於重新啟動或取消作業的一些控制方法。 系統會對每個 UploadOperation 自動處理應用程式事件 (例如暫停或終止) 和連線變更;在應用程式暫停期間上傳仍將繼續,或在應用程式終止之後會暫停或持續下去。此外,設定 CostPolicy 屬性將指出您的應用程式是否開始上傳,而且網際網路連線會使用計量付費網路。

以下的範例會逐步引導您建立和初始化基本上傳,以及如何列舉和重新引入之前應用程式工作階段中的持續作業。

上傳檔案

上傳的建立從 BackgroundUploader 開始。這個類別用來提供讓您的應用程式先設定上傳,再建立結果 UploadOperation 的方法。下列範例示範如何使用必要的 UriStorageFile 物件來執行這項操作。

  1. 識別上傳的檔案和目的地

    在開始建立 UploadOperation 之前,我們必須識別要上傳的目標位置 URI,以及要上傳的檔案。在下列範例中,填入 uriString 值的方式是使用 UI 輸入中的字串,而填入 file 值的方式則是使用 PickSingleFileAsync 操作傳回的 StorageFile 物件。

    
    function uploadFile() {
        var filePicker = new Windows.Storage.Pickers.FileOpenPicker();
        filePicker.fileTypeFilter.replaceAll(["*"]);
    
        filePicker.pickSingleFileAsync().then(function (file) {
            if (!file) {
                printLog("No file selected");
                return;
            }
    
            var upload = new UploadOp();
            var uriString = document.getElementById("serverAddressField").value;
            upload.start(uriString, file);
    
            // Store the upload operation in the uploadOps array.
            uploadOperations.push(upload);
        });
    }
    
    
    
  2. 建立和初始化上傳作業

    在上一個步驟中,uriStringfile 值已傳遞至我們下一個範例 UploadOp 的執行個體,這兩個值將被用來設定和啟動新的上傳操作。首先,會剖析 uriString 以建立必要的 Uri 物件。

    接下來,BackgroundUploader 會使用所提供之 StorageFile (file) 的屬性來填入要求標頭,並以 StorageFile 物件來設定 SourceFile 屬性。接著會呼叫 SetRequestHeader 方法,插入以字串方式提供的檔案名稱和 StorageFile.Name 屬性。

    最後,BackgroundUploader 會建立 UploadOperation (upload)。

    
    function UploadOp() {
        var upload = null;
        var promise = null;
    
        this.start = function (uriString, file) {
            try {
            
                var uri = new Windows.Foundation.Uri(uriString);
                var uploader = new Windows.Networking.BackgroundTransfer.BackgroundUploader();
    
                // Set a header, so the server can save the file (this is specific to the sample server).
                uploader.setRequestHeader("Filename", file.name);
    
                // Create a new upload operation.
                upload = uploader.createUpload(uri, file);
    
                // Start the upload and persist the promise to be able to cancel the upload.
                promise = upload.startAsync().then(complete, error, progress);
            } catch (err) {
                displayError(err);
            }
        };
        // On application activation, reassign callbacks for a upload
        // operation persisted from previous application state.
        this.load = function (loadedUpload) {
            try {
                upload = loadedUpload;
                promise = upload.attachAsync().then(complete, error, progress);
            } catch (err) {
                displayError(err);
            }
        };
    }
    
    
    

    請注意,非同步方法呼叫是使用 JavaScript Promise 定義的。看看上個範例的行:

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

    非同步呼叫後面跟著一個指示方法的 then 陳述式,由應用程式定義,會在非同步方法呼叫傳回結果時呼叫它。如需這種程式設計模式的詳細資訊,請參閱使用 Promise 在 JavaScript 的非同步程式設計

上傳多個檔案

  1. 識別上傳的檔案和目的地

    在使用一個 UploadOperation 傳輸多個檔案的案例中,程序會照一般的方法開始,也就是先提供必要的目的地 URI 和本機檔案資訊。就像上一節的範例,使用者以字串提供 URI,而 FileOpenPicker 可以用來透過使用者介面指出檔案。不過,在這個案例中,應用程式應該改為呼叫 PickMultipleFilesAsync 方法,啟用透過 UI 選取多個檔案的功能。

    
    
    function uploadFiles() {
       var filePicker = new Windows.Storage.Pickers.FileOpenPicker();
       filePicker.fileTypeFilter.replaceAll(["*"]);
    
       filePicker.pickMultipleFilesAsync().then(function (files) {
          if (files === 0) {
             printLog("No file selected");
    	        return;
          }
    
          var upload = new UploadOperation();
          var uriString = document.getElementById("serverAddressField").value;
          upload.startMultipart(uriString, files);
    
          // Persist the upload operation in the global array.
          uploadOperations.push(upload);
       });
    }
    
    
  2. 針對提供的參數建立物件

    接下來的兩個範例使用單一範例方法 startMultipart 中的程式碼,並在上個步驟結束時呼叫它。為了清楚說明,已將建立 BackgroundTransferContentPart 物件陣列方法中的程式碼與建立結果 UploadOperation 的程式碼分開。

    首先,使用者提供的 URI 字串被初始化為 Uri。接下來,傳送給這個方法的 IStorageFile 物件陣列 (files) 會不斷重複,並使用每個物件來建立新的 BackgroundTransferContentPart 物件,然後放置在 contentParts 陣列中。

    
    
    upload.startMultipart = function (uriString, files) {
        try {
            var uri = new Windows.Foundation.Uri(uriString);
            var uploader = new Windows.Networking.BackgroundTransfer.BackgroundUploader();
    
            var contentParts = [];
            files.forEach(function (file, index) {
                var part = new Windows.Networking.BackgroundTransfer.BackgroundTransferContentPart("File" + index, file.name);
                part.setFile(file);
                contentParts.push(part);
            });
    
    
  3. 建立和初始化多部分上傳作業

    使用我們的 contentParts 陣列 (其中已填入代表每個要上傳的 IStorageFile 的所有 BackgroundTransferContentPart 物件),我們已準備好使用 Uri 來呼叫 CreateUploadAsync,以指示傳送要求的目的地。

    
            // Create a new upload operation.
            uploader.createUploadAsync(uri, contentParts).then(function (uploadOperation) {
    
               // Start the upload and persist the promise to be able to cancel the upload.
               upload = uploadOperation;
               promise = uploadOperation.startAsync().then(complete, error, progress);
            });
    
         } catch (err) {
             displayError(err);
         }
     };
    
    

在啟動時列舉持續作業

UploadOperation 完成或取消時,會釋放任何關聯的系統資源。不過,如果您的應用程式在這兩件事發生之前終止,就會暫停任何進行中的作業,而且仍會佔用與每個作業關聯的資源。如果這些操作沒有列舉且重新引回下一個應用程式工作階段,這些操作將不會完成,而且仍然會繼續佔用裝置資源。

  1. 在定義列舉持續作業的功能之前,我們必須建立一個陣列來包含其將傳回的 UploadOperation 物件:

    
    var uploadOperations = [];
    
    
    
  2. 接著我們要定義列舉持續作業的功能,然後將這些作業儲存在我們的陣列。 請注意,將回呼重新指派到 UploadOperation 時所呼叫的 load 方法 (應在應用程式終止期間都持續著),位於我們稍後在本節所定義的 UploadOp 類別中。

    
    function Windows.Networking.BackgroundTransfer.BackgroundUploader.getCurrentUploadsAsync() {
        .then(function (uploads) {
            for (var i = 0; i < uploads.size; i++) {
                var upload = new UploadOp();
                upload.load(uploads[i]);
                uploadOperations.push(upload);
            }
        }
    };
    
    
    
    • Applies to Windows Phone

    附註  

    在 Windows Phone,當您的應用程式不在前景時,背景傳輸會持續進行。因為在此狀況下您的應用程式並未執行,所以傳輸完成時不會收到通知。當您的應用程式繼續時,如果您只檢查已完成傳輸的進度,狀態會是 BackgroundTransferStatus.Running。不過,當您連接到上述範例程式碼的傳輸時,會引發工作完成處理常式,也會更新傳輸狀態。

要求逾時

要考量的主要連線逾時情況有兩種:

  • 建立要傳輸的新連線時,如果在五分鐘內未建立連線要求,將會中止該要求。

  • 建立連線之後,將中止任何在兩分鐘內未收到回應的 HTTP 要求訊息。

附註  在任一種情況下,假設有網際網路連線,背景傳輸最多會自動重試要求三次。在偵測不到網際網路連線的事件中,其他要求將等到偵測到連線為止。

偵錯指導方針

在 Microsoft Visual Studio 中停止偵錯工作階段就等同於關閉應用程式;PUT 上傳會被暫停,POST 上傳會被終止。即使在偵錯時,應用程式應該列舉然後重新啟動或取消任何之前仍然存在的下載。例如,如果偵錯工作階段與之前的操作無關,您可以在應用程式啟動時,讓應用程式取消已列舉的持續上傳作業。

偵錯工作階段期間在應用程式啟動時列舉下載/上傳,如果該偵錯工作階段與之前的作業無關,您可以讓應用程式取消它們。請注意,如果有 Visual Studio 專案更新,像是變更應用程式資訊清單,而應用程式已解除安裝並重新部署,則 GetCurrentUploadsAsync 無法列舉使用前一個應用程式部署建立的作業。

如需詳細資訊,請參閱偵錯和測試 Windows 市集應用程式

開發期間使用背景傳送時,您可能會面臨使用中及已完成傳送作業的內部快取不同步的情況。這會導致無法開始新的傳送作業或無法與現有的作業和 BackgroundTransferGroup 物件互動。在某些情況下,嘗試與現有作業互動會造成當機。如果 TransferBehavior 屬性設為 Parallel,就會發生這種結果。這個問題只在開發期間的特定情況下發生,不適用於您應用程式的一般使用者。

使用 Visual Studio 時有四種情況會導致這個問題。

  • 您使用與現有專案相同的名稱但不同的語言 (例如,從 C++ 變更為 C#) 建立新的專案。
  • 您變更現有專案中的目標架構 (例如,從 x86 變更為 x64)。
  • 您變更現有專案中的文化特性 (例如,從中性變更為 en-US)。
  • 您在現有專案的套件資訊清單中新增或移除功能 (例如,新增 [企業驗證])。
一般應用程式服務,包括新增或移除功能的資訊清單更新,並不會在應用程式的一般使用者部署上引起這個問題。

若要解決這個問題,請完整解除安裝應用程式的所有版本,然後使用新的語言、架構、文化特性或功能來重新部署。這個操作可以透過 [開始] 畫面或使用 PowerShell 和 Remove-AppxPackage Cmdlet 來完成。

摘要與後續步驟

在這個主題中,我們檢閱如何以 JavaScript 使用 Background Transfer API 來上傳檔案。

您也可以在 Windows 市集應用程式下載檔案。如需核心概念與範例說明,請參閱如何下載檔案

相關主題

其他
存取連線與數據傳輸方案資訊
使用 Promise 在 JavaScript 的非同步程式設計
使用 JavaScript 建立您的第一個 Windows 執行階段應用程式
如何設定網路功能
如何使用 WinJS.xhr 下載檔案
參考
BackgroundUploader
UploadOperation
Windows.Networking.BackgroundTransfer
範例
背景傳輸範例
HttpClient 範例
如何下載檔案
Windows.Networking.BackgroundTransfer
背景傳輸範例

 

 

顯示:
© 2014 Microsoft