Отправка файла (HTML)

[ Эта статья адресована разработчикам приложений среды выполнения Windows для Windows 8.x и Windows Phone 8.x. При разработке приложений для Windows 10 см. раздел последняя документация]

В этом разделе будет описана отправка данных или файла с устройства в Интернет.

Приложения могут использовать описанные в этом разделе API, чтобы обеспечить взаимодействие с веб-службами для потребления или совместного использования распространенных форматов мультимедиа, таких как фотографии, музыка и видео.

Для выполнения крупных, потоковых или составных передач (видео, музыки и больших изображений), которые могут длиться в течение нескольких рабочих циклов приложения или при различных режимах доступности сети, приложение может использовать Background Transfer.

Чтобы получить представление о фоновой передаче данных на высоком уровне, см. Передача данных в фоновом режиме.

Необходимые условия

Общие рекомендации по созданию приложения Магазина Windows на JavaScript см. в разделе Создание первого приложения среды выполнения Windows на JavaScript. Для завершения асинхронных операций в этом разделе также используются объекты Promise в JavaScript. Подробнее об этой технике программирования: Асинхронное программирование на JavaScript с использованием объектов Promise.

Чтобы подготовить приложение для работы в сети, необходимо настроить такую возможность в файле проекта Package.appxmanifest. Определение всех сетевых возможностей см. в разделе Как настроить возможности сетевой изоляции.

Следующие примеры фоновой передачи используют JavaScript и основаны на образце передачи данных в фоновом режиме.

Операции передачи данных в фоновом режиме

При использовании функции передачи данных в фоновом режиме передача происходит в UploadOperation, который обеспечивает доступ к методам управления, позволяющим начинать операцию заново или отменять ее. События приложения (например, приостановка или завершение работы) и изменения сетевого подключения обрабатываются системой автоматически в соответствии с UploadOperation. Отправки будут продолжаться в периоды приостановки приложения, либо будут приостанавливаться и сохраняться в случаях завершения работы приложения. Можно также установить свойство CostPolicy, которое определяет, будет ли ваше приложение начинать отправки, если подключение к Интернету осуществляется через сеть с лимитным тарифным планом.

В следующих примерах будет показано, как создать и инициализировать простую отправку, а также как перечислить и воспроизвести операции, сохраненные в предыдущем сеансе приложения.

Отправка файла

Создание отправки начинается с BackgroundUploader. Этот класс используется для предоставления методов, которые позволяют приложению настраивать параметры отправки перед созданием итоговой операции UploadOperation. В следующем примере показано, как это сделать с необходимыми объектами Uri и StorageFile.

  1. Определение файла и места назначения отправки

    Прежде чем приступить к созданию UploadOperation, нужно определить URI местоположения отправки и файл, который будет отправлен. В следующем примере значение uriString заполняется строкой, введенной в пользовательском интерфейсе, а значение file определяется объектом StorageFile, возвращенным в результате операции PickSingleFileAsync.

    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. Создание и инициализация операции отправки

    В предыдущем шаге значения uriString и file передаются экземпляру следующего примера, UploadOp, где они применяются для настройки и запуска новой операции отправки. Сначала проводится анализ uriString для создания необходимого объекта Uri.

    Затем на основе свойств предоставленного StorageFile (file) BackgroundUploader заполняет заголовок запроса и задает свойство SourceFile с использованием объекта StorageFile. Далее вызывается метод 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);
            }
        };
    }
    

    Обратите внимание на асинхронные вызовы метода, определенные при помощи объектов Promise на JavaScript. Рассмотрим строку из последнего примера:

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

    За вызовом асинхронного метода следует оператор "then", указывающий определенные приложением методы, которые вызываются при возврате результата из асинхронного метода. Подробнее об этой технике программирования: Асинхронное программирование на JavaScript с использованием объектов Promise.

Отправка нескольких файлов

  1. Определение файлов и места назначения для отправки

    В сценарии, включающем несколько файлов, которые передаются одним UploadOperation, процесс начинается обычным способом, указывая необходимый универсальный код ресурса (URI) назначения и сведения о локальном файле. Аналогично примеру из предыдущего раздела, универсальный код ресурса (URI) предоставляется в виде строки пользователем и FileOpenPicker можно использовать для указания файлов также через пользовательский интерфейс. Однако в этом сценарии приложение должно вызвать метод PickMultipleFilesAsync, чтобы разрешить выбор нескольких файлов через пользовательский интерфейс.

    
    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 заполнен всеми объектами BackgroundTransferContentPart, каждый из которых представляет IStorageFile для отправки, мы готовы вызвать CreateUploadAsync, используя Uri для указания, куда будет направлен запрос.

            // 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. Затем определяем функцию, которая перечисляет сохраненные операции и сохраняет их в нашем массиве. Обратите внимание, что метод load, вызываемый для переназначения обратных вызовов операции UploadOperation, если она сохраняется при завершении работы приложения, содержится в классе 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);
            }
        }
    };
    

    Примечание  

    Для универсальных приложений Windows Phone передачи данных в фоновом режиме продолжаются, когда приложение находится не на переднем плане. Поскольку приложение в этом сценарии не выполняется, оно не получает уведомления при завершении передачи. Если при возобновлении работы приложения проверить ход выполнения завершенной передачи данных, его состояние будет BackgroundTransferStatus.Running. Тем не менее при подключении к передаче, как показано в примере кода выше, обработчик выполнения задач будет вызван и состояние передачи будет обновлено.

Тайм-ауты запросов

Таким образом, следует учитывать два основных сценария тайм-аута подключения.

  • При отсутствии ответа на запрос нового подключения для передачи в течение пяти минут такой запрос отменяется.

  • Если подключение установлено, любой HTTP-запрос отменяется при отсутствии ответа в течение двух минут.

Примечание  В данных сценариях при условии наличия подключения к Интернету функция передачи данных в фоновом режиме автоматически повторит отправку запроса до трех раз. Если подключение к Интернету не было обнаружено, дополнительные запросы будут ожидать его обнаружения.

 

Руководство по отладке

Остановка сеанса отладки в Microsoft Visual Studio сопоставима с закрытием приложения: отправки PUT при этом приостанавливаются, а отправки POST завершаются. Даже в процессе отладки ваше приложение должно перечислить, а затем перезапустить или отменить любые оставшиеся отправки. Например, можно сделать так, чтобы приложение отменяло перечисленные сохранившиеся операции отправки при запуске приложения, если предыдущие операции не имеют значения для данного сеанса отладки.

Можно сделать, чтобы при перечислении скачиваний и отправок во время запуска приложения в процессе сеанса отладки приложение отменяло их, если для данного сеанса отладки предыдущие операции не важны. Обратите внимание, что при наличии обновлений проекта Visual Studio, таких как изменения в манифесте приложения, когда приложение удаляется и развертывается заново, GetCurrentUploadsAsync не может перечислить операции, созданные при предыдущем развертывании.

Дополнительную информацию см. в разделе Отладка и тестирование приложений Магазина Windows с помощью Visual Studio.

Если при развертывании вы используете фоновую передачу данных, синхронизация внутреннего кэша активных и завершенных операций передачи может быть нарушена. В результате этого запуск новой операции передачи или взаимодействие с существующими операциями и объектами BackgroundTransferGroup может стать невозможным. В ряде случаев попытка взаимодействия с существующими операциями способна вызвать сбой. Это может произойти, если свойство TransferBehavior задано как Parallel. Такая проблема присуща определенным сценариям во время разработки и не затрагивает конечных пользователей приложения.

Проблема может возникнуть в четырех сценариях с использованием Visual Studio:

  • если вы создаете новый проект с таким же именем приложения, как в существующем проекте, но на другом языке (например, не C++, а C#);
  • если вы изменяете архитектуру конечного объекта (например, с x86 на x64) в существующем проекте;
  • если вы изменяете культуру (например, с нейтральной на en-US) в существующем проекте;
  • если вы добавляете или удаляете возможность в манифесте пакета (например, добавляете корпоративную аутентификацию) в существующем проекте.

Обычное обслуживание приложения, включая обновления манифеста, добавляющие или удаляющие возможности, не вызывает данную проблему при развертывании приложения у конечных пользователей.

Чтобы обойти проблему, полностью удалите все версии приложения и повторите развертывание с новым языком, архитектурой, культурой или возможностью. Это можно сделать, используя начальный экран или PowerShell и командлет Remove-AppxPackage.

Краткая сводка и дальнейшие действия

В этой теме мы рассмотрели процедуру отправки файлов с помощью API Background Transfer в JavaScript.

Вы можете также скачивать файлы в ваше приложение Магазина Windows. Описание основных принципов и примеры см. в разделе Как скачать файл.

Связанные разделы

Прочие ссылки

Получение информации о подключении и тарифном плане

Асинхронное программирование на JavaScript с использованием объектов Promise

Создание первого приложения среды выполнения Windows на JavaScript

Как настроить возможности сети

Как скачать файл с помощью WinJS XHR

Ссылки

BackgroundUploader

UploadOperation

Windows.Networking.BackgroundTransfer

Примеры

Пример Background Transfer

Пример HttpClient

Как скачать файл

Windows.Networking.BackgroundTransfer

Пример передачи в фоновом режиме