【问题标题】:Using jQuery and iFrame to Download a File使用 jQuery 和 iFrame 下载文件
【发布时间】:2013-05-23 20:42:51
【问题描述】:

我有以下代码可以下载.csv 文件:

$.ajax({
    url: urlString,
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    cache: false,
    success: function(data) {
        if (data) {
            var iframe = $("<iframe/>").attr({
                src: data,
                style: "visibility:hidden;display:none"
            }).appendTo(buttonToDownloadFile);
        } else {
            alert('Something went wrong');
        }
    }
});

urlString 指向一个 Restful 服务,该服务生成 .csv 文件并返回分配给 iFrame 的 src 属性的文件路径。这适用于任何.csv 文件,但我遇到.xml 文件的问题。

当我使用相同的代码但将contentType 更改为text/xml 并使用它来下载.xml 文件时,这不起作用。

我可以在这里对.xml 文件使用相同的方法吗?

更新:

感谢 Ben 为我指明了正确的方向。事实证明我根本不需要 ajax 调用。相反,我可以只使用 iFrame 及其 url 属性来调用 Web 服务,它将生成内容、添加标头 (Content-Disposition),然后返回流。

【问题讨论】:

    标签: javascript jquery


    【解决方案1】:

    您也可以从虚拟锚元素下载它,即使数据是客户端的:

    /*
     * Create an anchor to some inline data...
     */
    
    var url = 'data:application/octet-stream,Testing%20one%20two%20three';
    var anchor = document.createElement('a');
        anchor.setAttribute('href', url);
        anchor.setAttribute('download', 'myNote.txt');
    
    /*
     * Click the anchor
     */
    
    // Chrome can do anchor.click(), but let's do something that Firefox can handle too
    
    // Create event
    var ev = document.createEvent("MouseEvents");
        ev.initMouseEvent("click", true, false, self, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
    
    // Fire event
    anchor.dispatchEvent(ev);
    

    http://jsfiddle.net/D572L/

    【讨论】:

    • 太棒了。这只是帮助我解决了一个难题(使用 $.ajax 输出生成的 PDF,以便您可以在单击下载链接时显示加载器,然后在将文件提供给浏览器后再次隐藏它。谢谢!!
    • 谢谢!它适用于与隐藏 iframe 相对的 ios。
    【解决方案2】:

    我猜问题在于大多数浏览器会尝试在浏览器本身中呈现 XML,而它们往往没有 CSV 处理程序,因此它们会自动默认提示用户下载文件。尝试修改 XML 文件的标题以强制下载。类似的东西(PHP 示例):

    header("Content-Type: application/force-download");
    header("Content-Type: application/octet-stream");
    header("Content-Type: application/download");
    header('Content-Disposition: attachment; filename="some filename"');
    

    这应该告诉大多数浏览器不要尝试打开文件,而是让用户下载文件并让操作系统决定如何处理它。

    如果您无法控制 XML 文件本身中的标头,您可以尝试使用服务器端脚本的变通方法。使用 JS 将 URL 传递给服务器端脚本:

    //build the new URL
    var my_url = 'http://example.com/load_file_script?url=' + escape(path_to_file);
    //load it into a hidden iframe
    var iframe = $("<iframe/>").attr({
        src: my_url,
        style: "visibility:hidden;display:none"
    }).appendTo(buttonToDownloadFile);
    

    在服务器端(你的http://example.com/load_file_script 脚本)你使用cURL/file_get_contents/wgets/[获取远程文件的一些其他机制]来获取远程文件的内容,添加Content-Disposition: attachment 标头,print 原始文件的代码。

    【讨论】:

    • 恐怕我不太了解您建议的解决方法。我的服务器是 .NET (WCF)。您是说我应该从服务器端添加标头吗?
    • 是的。如果您不控制 RESTful API,那么您无法仅使用 HTML/JS 设置标头。所以你要做的是在你的 .NET 服务器上创建一个脚本,它可以接收远程 URL 作为参数,去获取远程文件,用新的标题重新打包它,然后将它作为附件提供。
    • 我明白了。正如你所指出的,我需要所有 4 个标题吗?我应该在我的 javascript 中使用什么内容类型?
    • 不,不一定。 Content-Disposition: attachment; filename="some filename" 可能是您唯一需要的,但有些浏览器可能很挑剔。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-12
    • 2019-06-29
    • 2010-11-20
    • 1970-01-01
    • 2021-12-18
    相关资源
    最近更新 更多