为什么我的浏览器不能自动打开Java Servlet中的“另存为...”对话框?

时间:2011-06-23 13:03:20

标签: java javascript

我目前正在尝试让浏览器自动提示用户从服务器保存文件。我有一个Java Servlet编码如下:

private void doDownload( HttpServletRequest request, HttpServletResponse response){
    File f = new File(<filename.ext> //This is text file but I have tried with pdfs, gifs, zips
    ServletOutputStream op = response.getOutputStream();
    int length = 0;
    op = response.getOutputStream();
    String mimetype = context.getMimeType( f.getAbsolutePath() );
    resp.setContentType("application/x-download");
    response.setContentLength( (int)f.length() );
    response.setHeader("Content-disposition", "attachment; filename=<newFileName.ext>");
    byte[] bbuf = new byte[8192];
    DataInputStream in = new DataInputStream(new FileInputStream(f));

    while ((in != null) && ((length = in.read(bbuf)) != -1))
    {
        op.write(bbuf,0,length);
    }

    in.close();
    op.flush();
    op.close();
}

我正在使用Firefox进行测试,并且我正在运行Firebug。我可以看到Firebug响应包含我设置的标题,当请求是文本文件时,应该包含的所有文本都包含在响应中。

在客户端上,我让Javascript以异步方式发出请求,如下所示:

try{
    xmlhttp = window.XMLHttpRequest?new XMLHttpRequest(): new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e)
{

} 

xmlhttp.open("post", 'myUrl?action=download', true);
xmlhttp.send(null);

我可以看到请求与服务器联系并且响应是正确的,如上所述,我可以在Firebug响应输出中看到文本文件等。

问题是从这里没有任何反应,根本没有浏览器响应。我已经在互联网上搜索了正确的方法,但是我能找到的只是服务器需要将内容配置设置为“attachment; filename =”并且contentType应该设置为“application / x-download” ”。我已经尝试将contentType设置为“application / octet-stream”,但我尝试过的任何内容似乎都无效。

如果有什么事我做错了,请有人向我解释一下吗?

2 个答案:

答案 0 :(得分:1)

当使用XMLHttpRequest对象从服务器检索文档时,浏览器不会显示“另存为”对话框。这很简单,因为响应的解析和呈现由处理responseXML / responseText属性的客户端JavaScript控制到很好的程度,而不是浏览器的HTTP响应解析器和MIME处理程序。

如果浏览器自动开始处理这些内容,那么XMLHttpRequest对象的用途就会丢失,并且不能对浏览器的DOM进行部分页面更新(不是每个人都希望用AJAX做什么?)。

因此,如果您希望浏览器显示“另存为”对话框,则会触发一个事件,该事件将导致整页刷新,从而导致请求被发送到服务器,响应是文档应该显示出来。这可以通过

完成
  • 表单提交,或
  • 点击超文本链接(锚元素)或
  • 在页面中创建内联框架(iframe),并将source属性设置为要在框架中显示的文档。

答案 1 :(得分:0)

您必须让浏览器“访问”页面才能显示下载对话框。仅仅发送一个帖子请求是不够的。

使用JavaScript执行此操作的最佳方法可能是使用<form>动态生成action="/your/servlet/page"对象,然后使用JavaScript在表单对象上调用submit()(不要忘记将<form>添加到页面,否则无效。