为什么Microsoft Skydrive不下载多个文件,即使MS示例显示它? (wl.download)

时间:2014-01-03 21:47:37

标签: javascript onedrive live-sdk

摘要

我试图找出为什么wl.download函数不会下载多个文件,即使Microsoft示例似乎表明它们可以。 并且,似乎为您尝试下载的每个文件调用代码,但实际上只下载了一个文件。

详情 以下是您在 IE 11.x和Chrome 30.x

中尝试过如何查看此问题的详细信息

如果你愿意去: http://isdk.dev.live.com/dev/isdk/ISDK.aspx?category=scenarioGroup_skyDrive&index=0

您将能够运行一个示例应用程序,该应用程序允许您从skydrive下载文件。

注意:该应用确实要求您允许该应用访问您的skydrive。

到达目的地后,您会在页面右侧看到如下代码: enter image description here

更改一个值:选择:

您需要更改一个值:更改

select: 'single'

select: 'multi' 

允许您选择要下载到计算机的大量文件。如果您没有进行更改,那么您将无法在“文件”对话框中选择多个文件。

点击“开始运行”按钮

接下来,您会看到一个[Run]按钮来启动应用程序(代码示例上方)。 继续,然后单击该按钮。

选择要下载的文件

之后,只需浏览skydrive文件并在文件夹中选择多个文件,然后单击[打开]按钮。此时,您将看到其中一个文件实际下载,并且示例网页的底部(输出)部分显示了许多文件名。

我的问题

  1. 为什么其他人不下载,即使在循环中调用wl.download,就像在循环中调用console.log一样?

  2. 这是浏览器的已知限制吗?

  3. 这是skydrive API中的已知错误吗?
  4. 这只是示例代码中的错误吗?

2 个答案:

答案 0 :(得分:2)

这里的问题是对wl.download({ "path": file.id + "/content" })的调用存储了一些内部状态(除其他外,正在下载的文件及其当前状态)。通过循环遍历文件列表,该状态实际上被每次调用覆盖。当我尝试一次下载三个文本文件时,它总是最后一个实际下载的文件,而不是前两个文件。

这里的困难是下载以传统方式执行,服务器将Content-Disposition: attachment添加到响应标头以强制浏览器下载文件。因此,在下载实际完成时无法接收任何类型的通知,这意味着您无法连续执行下载以解决状态问题。

我认为可行的一种方法受到this question的启发。根据{{​​3}},如果我们将/content?suppress_redirects=true附加到其ID,我们就可以获得文件的下载链接。使用documentation方法,我们可以设置IFrame的src属性并以这种方式下载文件。这样可以正常工作,但由于缺少Content-Disposition: attachment响应标头,它只会强制下载浏览器无法原生显示的文件类型(zip文件,Exe文件等)。

以下是我在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"));
}

答案 1 :(得分:0)

您是否尝试将某些事件绑定到WL.download()方法?根据文件:

  

WL.download方法只接受一个参数:      required path参数指定要下载的文件的唯一SkyDrive文件ID。   如果WL.download方法调用不成功,则可以使用其then方法的onError参数来报告错误。在这种情况下,WL.download不支持onSuccess和onProgress参数。如果WL.download方法调用成功,实际下载文件的用户体验将根据使用的Web浏览器类型而有所不同。

也许您在日志中遇到一些错误以确定问题。

对我来说,没有检查文档的一个建议,我可以想到你不等待每个下载结束的事实。为什么不以这样的方式更改循环,只有当你知道当前没有其他下载正在运行时才调用WL.download()(比如只在success / complete事件中调用下一个WL.download):

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); 

    }
);