Почему Microsoft Skydrive не загружает несколько файлов, хотя это показывает пример MS? (Wl.download)

Резюме

Я пытаюсь выяснить, почему функция wl.download не загружает более одного файла, хотя примеры Microsoft, кажется, указывают, что они могут. И, кажется, код вызывается для каждого файла, который вы пытаетесь загрузить, но фактически загружается только один файл.

Подробности Вот подробности того, как вы можете увидеть эту проблему, которую я пробовал в IE 11.x и Chrome 30.x

Пожалуйста, перейдите по ссылке: http://isdk.dev.live.com/dev/isdk/ISDK.aspx?category=scenarioGroup_skyDrive&index=0

Вы сможете запустить пример приложения, которое позволяет загружать файлы с вашего skydrive.

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

Как только вы попадете туда, вы увидите код, который выглядит так на правой стороне страницы: введите описание изображения здесь

Изменить одно значение: выберите:

Вам нужно изменить одно значение: изменить

select: 'single' в

select: 'multi' 

что позволит вам выбрать множество файлов для загрузки на ваш компьютер. Если вы не внесете это одно изменение, вы не сможете выбрать более одного файла в диалоговом окне "Файл".

Нажмите кнопку Run, чтобы начать

Далее вы увидите [Run] кнопка для запуска приложения (над примером кода). Идите вперед и нажмите эту кнопку.

Выберите файлы для загрузки

После этого просто просмотрите файлы Skydrive, выберите более одного в папке и нажмите кнопку [Открыть]. В этот момент вы увидите, что один из файлов действительно загружается, и в нижней части (на выходе) примера веб-страницы отображается несколько имен файлов.

Мои вопросы

  1. Почему другие не загружаются, даже если wl.download вызывается в цикле, так же как console.log вызывается в цикле?

  2. Это известное ограничение браузера?

  3. Это известная ошибка в skydrive API?
  4. Это просто ошибка в примере кода?

2 ответа

Решение

Проблема здесь в том, что вызов wl.download({ "path": file.id + "/content" }) хранит некоторое внутреннее состояние (среди прочего, загружаемый файл и его текущий статус). Зацикливая список файлов, это состояние фактически перезаписывается при каждом вызове. Когда я пытался загрузить три текстовых файла одновременно, это всегда был последний загруженный файл, а не первые два.

Сложность заключается в том, что загрузки выполняются традиционным способом, в результате чего сервер добавляет Content-Disposition: attachment в заголовки ответа, чтобы заставить браузер загрузить файл. Из-за этого невозможно получить уведомление любого типа, когда загрузка фактически завершена, что означает, что вы не можете выполнять загрузку последовательно, чтобы обойти проблему состояния.

Один из подходов, который, как я думал, может сработать, вдохновлен этим вопросом. Согласно документации, мы можем получить ссылку на скачивание файла, если добавим /content?suppress_redirects=true к его идентификатору. Используя этот подход, мы можем установить src свойство IFrame и скачать файл таким образом. Это работает нормально, но оно будет принудительно загружать только те типы файлов, которые браузер не может отображать изначально (zip-файлы, exe-файлы и т. Д.) Из-за отсутствия Content-Disposition: attachment заголовок ответа.

Вот что я использовал в Interactive Live SDK.

WL.init({ client_id: clientId, redirect_uri: redirectUri });

WL.login({ "scope": "wl.skydrive wl.signin" }).then(
    function(response) {
        openFromSkyDrive();
    },
    function(response) {
        log("Failed to authenticate.");
    }
);

function openFromSkyDrive() {
    WL.fileDialog({
        mode: 'open',
        select: 'multi'
    }).then(
        function(response) {
            log("The following file is being downloaded:");
            log("");

            var files = response.data.files;
            for (var i = 0; i < files.length; i++) {
                var file = files[i];
                log(file.name);

                WL.api({
                    path: file.id + "/content?suppress_redirects=true",
                    method: "GET"
                }).then(
                    function (response) {                    
                        var iframe = document.createElement("iframe"); 
                        iframe.src = response.location;             
                        iframe.style.display = "none";
                        document.body.appendChild(iframe); 
                    },
                    function (responseFailed) {
                        log("Error calling API: " + responseFailed.error.message);
                    } 
                );

            }
        },
        function(errorResponse) {
            log("WL.fileDialog errorResponse = " + JSON.stringify(errorResponse));
        }
    );
}

function log(message) {
    var child = document.createTextNode(message);
    var parent = document.getElementById('JsOutputDiv') || document.body;
    parent.appendChild(child);
    parent.appendChild(document.createElement("br"));
}

Вы пытались привязать некоторые события к методу WL.download()? Согласно документации:

Метод WL.download принимает только один параметр: обязательный параметр path указывает уникальный идентификатор файла SkyDrive для загружаемого файла. Если вызов метода WL.download не выполнен, вы можете использовать параметр onError его метода then, чтобы сообщить об ошибке. В этом случае WL.download не поддерживает параметры onSuccess и onProgress. Если вызов метода WL.download выполнен успешно, пользовательский интерфейс для фактической загрузки файлов будет отличаться в зависимости от типа используемого веб-браузера.

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

Для меня одно предложение, не проверив документацию, я могу подумать о том, что вы не ждете окончания каждой загрузки. Почему бы не изменить свой цикл таким образом, чтобы вы вызывали WL.download() только в том случае, если вы знаете, что в данный момент не выполняется другая загрузка (как, например, вызов следующего WL.download только в событии success/complete):

WL.download({ "path": file.id + "/content" }).then(
    function (response) {
        window.console && console.log("File downloaded."); 
        //call the next WL.download() here <!-----------------
    },
    function (responseFailed) {
        window.console && console.log( "Error downloading file: " + responseFailed.error.message); 

    }
);
Другие вопросы по тегам