如何让浏览器提示用户保存服务器动态生成的文件?

时间:2013-12-21 02:00:02

标签: javascript ajax file browser save

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

$.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

我也有Cookie工作,在200 OK行之后放置以下内容:

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。

1 个答案:

答案 0 :(得分:9)

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