【问题标题】:Why doesn't Microsoft Skydrive download multiple files even though MS example shows it? (wl.download)为什么即使 MS 示例显示 Microsoft Skydrive 不下载多个文件? (wl.下载)
【发布时间】:2014-01-21 16:35:05
【问题描述】:

总结

我试图找出为什么 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. 这只是示例代码中的一个错误吗?

【问题讨论】:

    标签: javascript onedrive live-sdk


    【解决方案1】:

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

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

    我认为可能可行的一种方法是受到this question 的启发。根据documentation,如果我们将/content?suppress_redirects=true 附加到文件的id,我们可以获得文件的下载链接。使用this 方法,我们可以设置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"));
    }
    

    【讨论】:

    • nick_w => 这是我在任何论坛上发帖时收到的有史以来最好的、击倒的最佳答案之一,尤其是 SO。非常感谢您如此仔细地查看我的原始问题,提供解决方案,很好地解释它并提供完整的示例代码,我能够将其复制/粘贴到 LIVE SDK 站点并运行。我投票给你,希望你能得到赏金。你应得的。谢谢讨论。我假设您处于 IT 世界的架构师级别,因为您不仅实施了解决方案,而且详细解释了它。继续编码。
    【解决方案2】:

    您是否尝试将某些事件绑定到 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); 
    
        }
    );
    

    【讨论】:

    • 首先,感谢您阅读并提供一些意见。是的,我也调查了您提交的选项。但是,如果您运行了代码并尝试了它,您会发现,就像我所做的那样,then() 函数都没有被调用过。但是,如果您在 wl.download 上执行以下代码,.then(console.log(file.name));代码确实运行。 Live API 或文档中似乎存在错误。这是我的问题的一部分,因为我无法获得文件下载活动的状态。再次感谢
    猜你喜欢
    • 1970-01-01
    • 2013-05-13
    • 2015-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-09
    • 1970-01-01
    • 2015-08-31
    相关资源
    最近更新 更多