【问题标题】:How do I get browser to prompt user to save a file dynamically generated by server?如何让浏览器提示用户保存服务器动态生成的文件?
【发布时间】:2014-01-09 23:10:26
【问题描述】:

客户端使用 jquery ajax 提交 post 请求,如下图所示:

$.ajax({
    url: "/xxx?request1", 
    data: theParams,
    type: 'post',
    error: function(XMLHttpRequest, textStatus, errorThrown){
        // error handling
    },
    success: function(data){
    var theResult = JSON.parse(data);
        // success handling
    }
});

Apache 配置为将带有/xxx? 的请求传递给自定义应用程序。应用程序处理请求并返回信息。通常,此信息以 JSoN 形式返回,并使用 jquery/javascript 显示在“成功处理”部分。应用程序在写入 JSON 之前写入以下标头(然后通过 apache 返回):

HTTP/1.0 200 OK
Connection: close
Server: MyServer v. 0.826
Content-Type: text/html

我还可以通过在 200 OK 行之后放置以下内容来使用 cookie:

Set-Cookie: cookie_name=value; Domain=example.com; Path=/; Expires=Fri, 21-Mar-2014 01:40:22 GMT; HttpOnly

在一种情况下,我希望用户能够保存返回的数据(作为纯文本文件)。但这是我遇到问题的地方。

如果我使用 JavaScript 打开一个窗口并将数据写入新窗口,我发现 Safari 和 Chrome 都禁用了“另存为...”菜单选项(在 Mac 上)。

(我有一个使用 base64 URI 的版本,但相对于网站的其他部分而言,它看起来很粗糙。)

然后我开始尝试包含 Content-Disposition: attachment; filename=file.txt 标头,但我永远无法让浏览器产生提示。我尝试将此标题放在 200 OK 行之后,以及稍后:

Content-Type: text/plain
Content-Disposition: attachment; filename=file.txt

除了不确定Content-Disposition 标头的确切格式之外,我还不确定Content-Type 是否正确,或者ajax 处理程序代码中是否存在阻止保存的内容。

我试图找到将所有内容组合在一起的示例,但只能找到部分,显然我无法将它们正确组合在一起。有什么建议吗?

我只针对现代浏览器、三个主要平台(Mac/Windows/Linux)和客户端的 HTML5/JavaScript。

【问题讨论】:

    标签: javascript ajax file browser save


    【解决方案1】:

    Content-Disposition: attachment 是正确的标头,但浏览器只有在直接加载文件时才服从它。 使用 AJAX(甚至通过 jQuery)将不起作用。

    有办法做到这一点。 阅读this answer 中的完整说明,但基本上你只需在success 函数中编写:

    window.location = "data:application/octet-stream," + encodeURIComponent(theResult);
    

    编辑: FileSaver.js 提供了一个包装器 improving browser compatibility 并添加了对兼容浏览器的文件名的支持:

    var blob = new Blob(["Hello, world!"], {type: "text/plain;charset=utf-8"});
    saveAs(blob, "hello world.txt");
    

    【讨论】:

    • 我无法将文件保存在服务器上,这解释了我在使用 Content-Disposition 时遇到的困难。您提供的链接提供了一种方式,现在“保存”菜单项可用。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2011-01-23
    • 1970-01-01
    • 1970-01-01
    • 2013-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-20
    相关资源
    最近更新 更多