【问题标题】:Browser does not generate file download dialog浏览器不生成文件下载对话框
【发布时间】:2012-07-11 09:51:18
【问题描述】:

我目前的情况是 JavaScript 客户端有一堆数据我 POST 到服务器以处理/翻译成不同的格式(例如 CSV),现在我想将转换后的数据从服务器发送到客户端。

我设置了响应的内容类型,但是浏览器没有生成文件对话框。

这是我的控制器的样子:

@RequestMapping(value="/exportBoxes/{type}/{filename:.+}", method=RequestMethod.POST)
public String exportBoxes(@RequestBody String body,      @PathVariable String type,
                          @PathVariable String filename, HttpServletResponse response) throws IOException
{
    JsonObject jsonObject = new JsonParser().parse(body).getAsJsonObject();

    //grab the data from the JSONobject
    String data = jsonObject.get("JSONdata").getAsString();

    //create output stream writer
    PrintWriter p = new PrintWriter(response.getOutputStream());

    //set response type and print header
    if(type.equals("csv"))
    {
        response.setContentType("text/csv");
        response.setHeader("Content-Disposition", "attachment; filename=\"" + filename + "\"");
    }

    //print the points to the file
    for(int i = 0; i < splitPoints.length; i++)
    {
        //print remainder of CSV file - abstracted
    }

    p.flush(); //flush the stream
    response.flushBuffer();
    p.close(); //close the stream

    return "success";
}

这是 POST 数据的客户端函数:

DAService.prototype.exportBoxes = function(type, filename, data) {
    var path       = 'api/rest/da/exportBoxes/' + type + '/' + filename
    var url        = (this.connection) ? this.connection + path : path;
    var JSONdata   = '';
    var returnType = ''

    //create JSON string to pass to Java controller
    if(type == 'csv')
    {
        JSONdata   = '{ "JSONdata" : "' + data.replace(/ /g, '') + '" }';
        returnType = 'text/csv';
    }
    else
    {
        throw "Invalid export format " + type;
    }

    $j.ajax({
        url:         url,
        contentType: 'application/json',
        type:        'POST',
        dataType:    returnType,
        data:        JSONdata,
        success: function(returnedData){
            console.log("exportBox successful");
        },
        error: function(x,y,z) {
            console.log("exportBox failed with error '" + y + "'");
        },
        complete: function(empty, textStatus){
            console.log("exportBox complete textStatus='" + textStatus + "'");
        }
    });
};

此代码不会生成错误,并且服务器的响应中包含 CSV 文件,我只是无法让客户端生成下载对话框。

我错过了一件我看不到的东西,有人可以帮我吗?

【问题讨论】:

  • 也许可以试试 application/octet-stream 作为内容类型。
  • @nkr 那也没有生成文件对话框。
  • 如果您不使用$.ajax,而是将表单发布到隐藏的&lt;iframe&gt;,会发生什么情况?
  • @Pointy 我是 Web 开发新手,将表单发布到隐藏的 iframe 会做什么?
  • 好吧,我不是很肯定,但我怀疑问题在于,当附件返回以响应 XHR 时,浏览器不会注意附件。但是,如果你真的发布了一个表格,那么它应该注意。我会输入一个答案来进一步解释。

标签: java javascript jquery spring-mvc


【解决方案1】:

您可能想尝试发布表单而不是使用$.ajax

var form = $('<form/>', {
  action: url,
  method: 'POST',
  css: { display: 'none' },
  html: $('<input/>', {name: 'JSONdata', value: data.replace(/ /g, '') })
});
$('body').append(form);
form.submit();

(我没有测试过。)关键是当你真正发布一个表单时,浏览器知道解释响应正文,它应该注意到你的附件。

【讨论】:

  • 这确实让浏览器注意到了请求,但是如何使用这种方法将数据传递给服务器呢?
  • 抱歉,我输入的字段不正确;我更新了答案。 &lt;input&gt; 的“值”应该像我刚才所做的那样更改,以匹配您在发布的代码中所做的。
  • 这很好用!你知道一种打开文件对话框的方法吗?这样客户就可以将文件保存在他们想要的任何地方?
  • 嗯,一些浏览器有用户控制的选项来保存文档,或者启动外部应用程序等;页面上的 JavaScript 无法控制。是这个意思吗?
  • 是的,我希望浏览器会在服务器响应后打开类似于保存文件对话框的内容,但只需转到下载文件夹就可以了。谢谢!
猜你喜欢
  • 2011-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-12
  • 2015-05-02
  • 2017-08-15
  • 1970-01-01
相关资源
最近更新 更多