1

概括

我试图找出为什么 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。

到达那里后,您将在页面右侧看到如下所示的代码: 在此处输入图像描述

更改一个值:选择:

您需要更改一个值:更改

select: 'single'

select: 'multi' 

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

单击运行按钮开始

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

选择要下载的文件

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

我的问题

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

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

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

2 回答 2

2

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

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

我认为可能有效的一种方法是受到这个问题的启发。根据文档/content?suppress_redirects=true,如果我们附加到文件的 id ,我们可以获得文件的下载链接。使用这种方法,我们可以设置srcIFrame 的属性并以这种方式下载文件。这可以正常工作,但它只会强制下载由于缺少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"));
}
于 2014-01-10T08:54:56.723 回答
0

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

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

也许您在日志中遇到了一些错误以识别问题。

对我来说,一个没有检查文档的建议,我可以想到这样一个事实,即您不需要等待每次下载结束。为什么不改变你的循环,只在你知道当前没有其他下载正在运行时才调用 WL.download() (比如只在成功/完成事件中调用下一个 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); 

    }
);
于 2014-01-07T16:46:20.797 回答