Java webapp:添加内容处置标头以强制浏览器“另存为”行为
即使它不是 HTTP 1.1/RFC2616 的一部分,希望强制在浏览器中下载资源(而不是显示)的网络应用程序也可以使用 Content-Disposition
标头,例如这个:
Content-Disposition: attachment; filename=FILENAME
尽管它只在 RFC2183 中定义,而不是 HTTP 1.1 的一部分,但它可以按照需要在大多数 Web 浏览器中工作。
所以从客户端来看,一切都足够好了。
然而,在服务器端,就我而言,我有一个 Java Web 应用程序,我不知道应该如何设置该标头,特别是在以下情况下......
我将有一个文件(比如说称为“bigfile”)托管在 Amazon S3 实例上(我的 S3 存储桶应可使用部分地址进行访问,例如:files.mycompany.com/),以便用户能够访问此文件:files.mycompany.com/bigfile。
现在有没有一种方法可以制作 servlet (或 .jsp),以便在用户需要时始终添加 Content-Disposition
标头下载该文件?
代码是什么样子的?有什么陷阱(如果有的话)?
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-Disposition
header like this:
Content-Disposition: attachment; filename=FILENAME
Even tough it's only defined in RFC2183 and not part of HTTP 1.1 it works in most web browsers as wanted.
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...
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.
Now is there a way to craft a servlet (or a .jsp) so that the Content-Disposition
header is always added when the user wants to download that file?
What would the code look like and what are the gotchas, if any?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
正如 Pointy 指出的那样,我得到了这个工作。现在不是直接链接到资产(在我的例子中是 pdf),而是链接到名为 download.jsp 的 JSP,该 JSP 获取并解析 GET 参数,然后将 pdf 作为下载提供。
在这里下载
这是我使用的jsp代码。它在 IE8、Chrome 和 Firefox 中工作:
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.
Download here
Here's the jsp code I used. Its working in IE8, Chrome and Firefox:
您不会有直接引用该文件的 URL。相反,您将拥有一个指向 servlet 代码(或服务器端框架中某种操作代码)的 URL。反过来,在设置标头后,必须访问文件内容并将它们铲到客户端。 (您还需要记住根据需要处理缓存控制标头。)
HttpServletResponse 类具有可让您设置所需的所有标头的 API。您必须确保在开始转储文件内容之前设置标头,因为标头实际上必须在发送到浏览器的流中排在第一位。
这与您可能有一个可以即时生成下载的 servlet 的情况没有太大区别。
编辑为了后代,我将把这些内容留在这里,但我会注意到,当您存储<时,有(或可能有)某种方法可以将一些 HTTP 标头移交给 S3 /em> 一个文件,这样亚马逊会在文件送出时将其吐出。我不太确定你会如何做到这一点,我也不确定“Content-disposition”是一个可以这样设置的标头,但我会继续寻找。
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.)
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 before you start dumping out the file contents, because the headers literally have to come first in the stream being sent out to the browser.
This is not that much different from a situation where you might have a servlet that would generate a download on-the-fly.
edit I'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 store a 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.
将
.htaccess
文件放入根文件夹中,其中包含以下行:Put a
.htaccess
file in the root folder with the following line:我刚刚通过谷歌找到了这个。
我遇到了类似的问题,但我仍然想使用 Servlet(当我生成内容时)。
然而,在 Servlet 中,以下行就足够了。
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).
However the following line is all you need in a Servlet.