Java webapp:添加内容处置标头以强制浏览器“另存为”行为
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2405568/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java webapp: adding a content-disposition header to force browsers "save as" behavior
提问by SyntaxT3rr0r
Even though it's not part of HTTP 1.1/RFC2616 webapps that wish to force a resource to be downloaded(rather than displayed) in a browser can use the Content-Dispositionheader like this:
即使它不是 HTTP 1.1/RFC2616 webapps 的一部分,希望强制在浏览器中下载(而不是显示)资源,也可以使用这样的Content-Disposition标头:
Content-Disposition: attachment; filename=FILENAME
Even tough it's only defined in RFC2183 and notpart of HTTP 1.1 it works in most web browsers as wanted.
即使很难,它也只在 RFC2183 中定义,而不是HTTP 1.1 的一部分,它可以根据需要在大多数 Web 浏览器中工作。
So from the client side, everything is good enough.
所以从客户端来说,一切都足够好了。
However on the server-side, in my case, I've got a Java webapp and I don't know how I'm supposed to set that header, especially in the following case...
但是在服务器端,就我而言,我有一个 Java webapp,但我不知道应该如何设置该标头,尤其是在以下情况下...
I'll have a file (say called "bigfile") hosted on an Amazon S3 instance (my S3 bucket shall be accessible using a partial address like: files.mycompany.com/) so users will be able to access this file at files.mycompany.com/bigfile.
我将在 Amazon S3 实例上托管一个文件(例如称为“ bigfile”)(我的 S3 存储桶应可使用部分地址访问,例如:files.mycompany.com/),因此用户将能够在files 中访问此文件.mycompany.com/bigfile。
Now is there a way to craft a servlet(or a .jsp) so that the Content-Dispositionheader is always added when the user wants to download that file?
现在有没有办法制作servlet(或.jsp),以便Content-Disposition在用户想要下载该文件时始终添加标头?
What would the code look like and what are the gotchas, if any?
代码是什么样的,有什么问题(如果有的话)?
采纳答案by Pointy
You wouldn't have a URL that was a direct reference to the file. Instead, you'd have a URL that leads to your servlet code (or to some sort of action code in your server-side framework). That, in turn, would have to access the file contents and shovel them out to the client, after setting up the header. (You'd also want to remember to deal with cache control headers, as appropriate.)
您不会拥有直接引用该文件的 URL。相反,您将拥有一个指向 servlet 代码(或指向服务器端框架中的某种操作代码)的 URL。反过来,在设置标头后,必须访问文件内容并将它们推送给客户端。(您还需要记住处理缓存控制标头,视情况而定。)
The HttpServletResponse class has APIs that'll let you set all the headers you want. You have to make sure that you set up the headers beforeyou start dumping out the file contents, because the headers literally have to come first in the stream being sent out to the browser.
HttpServletResponse 类具有可让您设置所需的所有标头的 API。您必须确保在开始转储文件内容之前设置标题,因为标题必须在发送到浏览器的流中排在第一位。
This is not that much different from a situation where you might have a servlet that would generatea download on-the-fly.
这与您可能有一个可以即时生成下载的 servlet 的情况没有太大不同。
editI'll leave that stuff above here for posterity's sake, but I'll note that there is (or might be) some way to hand over some HTTP headers to S3 when you storea file, such that Amazon will spit those back out when the file is served out. I'm not exactly sure how you'd do that, and I'm not sure that "Content-disposition" is a header that you can set up that way, but I'll keep looking.
编辑为了后人的缘故,我将把这些东西留在上面,但我会注意到有(或可能有)某种方式在您存储文件时将一些 HTTP 标头移交给 S3 ,这样亚马逊就会将这些标头吐出文件送达时。我不确定你会怎么做,我不确定“内容处理”是一个你可以这样设置的标题,但我会继续寻找。
回答by Jonathan McK
I got this working as Pointy pointed out. Instead of linking directly to the asset - in my case pdfs - one now links to a JSP called download.jsp which takes and parses GET parameters and then serves out the pdf as a download.
正如 Pointy 指出的那样,我得到了这个。不是直接链接到资产——在我的例子中是 pdfs——现在链接到一个名为 download.jsp 的 JSP,它接受并解析 GET 参数,然后将 pdf 作为下载提供。
Download here
在这里下载
Here's the jsp code I used. Its working in IE8, Chrome and Firefox:
这是我使用的jsp代码。它适用于 IE8、Chrome 和 Firefox:
<%@page session="false"
contentType="text/html; charset=utf-8"
import="java.io.IOException,
java.io.InputStream,
java.io.OutputStream,
javax.servlet.ServletContext,
javax.servlet.http.HttpServlet,
javax.servlet.http.HttpServletRequest,
javax.servlet.http.HttpServletResponse,
java.io.File,
java.io.FileInputStream"
%>
<%
//Set the headers.
response.setContentType("application/x-download");
response.setHeader("Content-Disposition", "attachment; filename=downloaded.pdf");
[pull the file path from the request parameters]
File file = new File("[pdf path pulled from the requests parameters]");
FileInputStream fileIn = new FileInputStream(file);
ServletOutputStream outstream = response.getOutputStream();
byte[] outputByte = new byte[40096];
while(fileIn.read(outputByte, 0, 40096) != -1)
{
outstream.write(outputByte, 0, 40096);
}
fileIn.close();
outstream.flush();
outstream.close();
%>
回答by BalusC
Put a .htaccessfile in the root folder with the following line:
将一个.htaccess文件与以下行的根文件夹:
Header set Content-Disposition attachment
回答by grayoctagon
I just found this via google.
我刚刚通过谷歌找到了这个。
And I had a simmilar problem, but I still want to use a Servlet (as I generate the Content).
我有一个类似的问题,但我仍然想使用一个 Servlet(当我生成内容时)。
However the following line is all you need in a Servlet.
但是,在 Servlet 中,您只需要以下行即可。
response.setHeader("Content-Disposition", "attachment; filename=downloadedData.json");

