背景: 在一个项目中,队友反应浏览器点击下载一个近100M的文件和 10+KB的文件,
下载保存提示框要等很长时间, 而且等待弹出的时间与文件大小成正比关系.
接着 ,找了一个有空的时间, 写了一个极简单的文件下载,使用servlet repsonse输出.
我的环境是一个500M的文件,好家伙 , IE8 CHROME 都要等待很久.
郁闷了..
好吧, 请同事也写一个DEMO吧. 咦..他也是200M的文件,访问他的WEB ,一两秒的时间就出来了.
问题
1.真的是WEB SERVER要读完文件才向broswer输出吗?
2.如果问题1是正确的,那我同事的WEB SERVER,我去访问就一两秒. 我访问自己的DEMO却要等20多秒才弹??
随后比较我的DEMO和我同事的DEMO代码.
相同的文件流读取.
不过发现代码不同了.
我用的 Content-type: application/octet-stream
他用的 Content-type: application/x-download
然后是相同的马上用servlet HttpServletResponse flushBuffer(),向浏览器输出头.
查了一遍mime. 我用的是标准的MIME, application/x-download却不存在.
而真实的项目 文件下载代码Content-type却没有写.
查了'
Beginning Java Networking'的书(
很旧的书).servlet HttpServletResponse flushBuffer() 明确的说明头信息是会马上从server输出.
和同事讨论, 他猜测是不同的浏览器对接受流下载的时候会分析http的header和body.
他的猜测 更坚定了上述中我对书中的认识.
那继续查资料. 终于在 "Servlet Best Practices, Part 3"找到我要的答案.
我最后使用 :
1. Content-type: xxxyyy 非标准的MIME.
2. Content-Disposition: attachment; filename=...
3. servlet HttpServletResponse flushBuffer() 马上送出一个只含头信息的HTTP包. 免的文件要是2GB+的文件,用户就要抓狂了....
译文:
servlet 最佳实践 -- 实践:没有形成理论之前的某些经验.
servlet中其它的编程提示.
给发送的文件使用上内容描述.
当我们正在使用像魔法一样的神奇的头部信息的题材,servlet开发人员经常会挣扎于寻找正确的头部信息的组合内容来给浏览器发送一个文件,同时这个文件打算是让浏览器触发一个文件保存的对话框的,而不是直接的打开查看或是浏览. 针对这一个目标, 我有一些好消息同时也有一些坏消息.
坏消息是:尽管HTTP的规范(请查阅HTTP/1.1,19.5.1章节)为文件下载提供了机制,然而许多浏览器会"自作多情"地去猜测服务端发送来的指令,并且比起服务端告诉的事,浏览器做一些认为自己应该的做的最好的行动.这些浏览器(包括MS IE 和Opera)会查看文件的扩展名和从得到的输入流的内容中去嗅出(文件类型).假如他们知道的是HTML或IMAGE内容,他们就会直接在自己那显示文件内容而不是响应一个文件下载对话框. 事实证明不是有100%可信的方式通过浏览器去下载一个文件(可以让用户保存起来).也许,通过努力的编程人员比起魔法师更像是炼金的术士,他们努力尝试地将粪土变成黄金.
好消息是如果正确的组合头部信息去做文件下载那么就是一个足够用的实践做法.带上这些特殊头部信息集,一个"兼容"的浏览器就会正常响应一个文件下载对话框,而不会像不"兼容"的浏览器,他们只为不是HTML和IMAGE文件打开下载对话框.
在这些文件类型(指HTML和IMAGE)中,当用户去使用右键菜单保存内容文件时,不兼容浏览器会直接显示文件.
例子 3-9 为发送文件展示最好的做法
// Set the headers. 发送头
res.setContentType("application/x-download");
res.setHeader("Content-Disposition", "attachment; filename=" + filename);
// Send the file. 发送文件体.
OutputStream out = res.getOutputStream( );
returnFile(filename, out); // Shown earlier in the chapter
译注: 此示例代码没有提示马上发送HTTP头信息,如果将HTTP头信息作一个小包马上发送,那么加上示例代码就可以让"兼容"浏览器迟早响应一个文件下载框. 假设目前的网络,去下载一个2~8G的文件.
首先:给Content-Type header设定一个非标准的值例如application/x-download.
如果这个头部信息是浏览器不认识那是非常重要的,因为当浏览器识别了内容的类型,那么浏览器经常会做一些特殊的事情.
然后为头部信息设定内容描述,值为attachment; filename=foo,这里的foo是文件下载框对话框中默认的文件名.
最后,作为二进制发送文件内容.二进制的数组内容可以来自文件系统也可以是动态生成的.
使用这些头部信息,那么输出的文件内容就会让大多数的浏览器响应文件下载框去让用户保存,
最糟糕的情况文件内容会显示在浏览器而不是保存.在response响应中没有一个标准的文件下载所有类型的文件.
最后的(一点提示),包括给servlet下载文件名作为额外的路径信息,也是有用的.
那个Servlet通过知道哪个文件要给用户下载就可以使用文件名,或是可以忽略额外的路径信息.无论哪个方式,它(下载文件名)总是也是有用的:因为文件名会出现在浏览器上作为将被保存资源文件的文件名. 同时浏览器经常会在文件下载提示框上使用文件名.
例如:使用/servlet/FileDownload/inventory.pdf?fileid=5. 而不是使用 /servlet/FileDownload?fileid=5
注:下面一小段不知道在书中哪个部分,就不翻译了. 我看的是网上的节选.
3. Microsoft documents Internet Explorer's deviant behavior, although I've found that reality doesn't exactly match the documentation.
4. The HTTP specification recommends setting the Content-Type to application/octet-stream. Unfortunately, this causes problems with Opera 6 on Windows (which will display the raw bytes for any file whose extension it doesn't recognize) and on Internet Explorer 5.1 on the Mac (which will display inline content that would be downloaded if sent with an unrecognized type).
原文:
Other Servlet Tips
Use Content-Disposition to Send a File
While we're on the subject of magic header incantations, servlet developers often struggle with finding the right header combination to send a browser a file that's intended for saving rather than viewing and thus triggers a "Save As" dialog. For the solution to this problem, I have some good news and some bad news.
The bad news is that although the HTTP specification provides a mechanism for file downloads (see HTTP/1.1, Section 19.5.1), many browsers second-guess the server's directives and do what they think is best rather than what they're told. These browsers--including Microsoft Internet Explorer and Opera--look at the file extension and "sniff" the incoming content. If they see HTML or image content, they inline-display the file contents instead of offering a Save As dialog.[3] Turns out there's no 100% reliable way to download a file across all browsers. Perhaps, with this effort, programmers are more like alchemists than magicians, trying in vain to turn lead into gold.
The good news is that the right combination of headers will download files well enough to be practical. With these special headers set, a compliant browser will open a Save As dialog, while a noncompliant browser will open the dialog for all content except HTML or image files. For these types it will display the content inline, where a user can use the menu to save the content. Example 3-9 shows the best technique for sending files.
Example 3-9: Sending a file for download
// Set the headers.
res.setContentType("application/x-download");
res.setHeader("Content-Disposition", "attachment; filename=" + filename);
// Send the file.
OutputStream out = res.getOutputStream( );
returnFile(filename, out); // Shown earlier in the chapter
First, set the Content-Type header to a nonstandard value such as application/x-download. It's very important that this header is something unrecognized by browsers because browsers often try to do something special when they recognize the content type.[4] Then set the Content-Disposition header to the value attachment; filename=foo, in which foo is substituted with the filename to be used by default in the Save As dialog. Finally, send the file content as bytes. The bytes can come from the filesystem or be dynamically generated.
Using these headers, the file content in the response will be saved by most browsers or, in worst cases, displayed inline where the user can save the file. There's no standard way to download multiple files in one response.
Finally, it can be useful to include the download file's name as extra path information to the servlet. The servlet can use the filename to learn which file to download, or it can ignore the extra path info. Either way, it's useful because the name appears to the browser as the name of the resource being retrieved, and browsers often use that name in the Save As dialog prompt. For example, instead of serving content from /servlet/FileDownload?fileid=5, serve it from /servlet/FileDownload/inventory.pdf?fileid=5.
分享到:
相关推荐
【标题】"my_broswer.rar_C#浏览器源码_CSharp 浏览器_浏览器_浏览器 C#" 提供的是一个使用C#编程语言实现的浏览器的源代码。C#(发音为"C sharp")是一种面向对象的编程语言,由微软公司开发,广泛应用于Windows...
在Android平台上,开发一个文件浏览器应用是一个常见的任务,它涉及到对文件系统操作的深入理解和UI组件的使用。本文将详细探讨如何使用ListView和File类来实现一个简单的“android_文件浏览器”。 首先,`ListView...
NPS浏览器-游戏目录包.zip
xdm 浏览器插件文件。 没有插件,xdm下载器不完整。
- `MyBrowser.cpp`, `MyBrowserView.cpp`, `MainFrm.cpp`, `MyBrowserDoc.cpp`等文件分别对应了MFC的主框架、视图、文档等类的实现,它们是MFC程序的基本结构。 - `UrlDlg.cpp`可能包含了输入URL的对话框实现,...
很抱歉,根据您提供的信息,"broswer.zip" 和 "broswer.rar" 是两个不同的压缩文件格式,通常 ".zip" 和 ".rar" 都是用来打包和压缩文件的常见格式。在此,我会根据这两个文件可能包含的IT知识进行阐述,但请注意,...
Java Web 运行开发环境和 Servlet 的开发部署 Java Web 运行开发环境是指 Java Web 应用的开发和部署所需的环境配置,包括 JDK、Tomcat 等。其中,JDK 是 Java 开发的基础环境,而 Tomcat 是一个 Servlet 和 JSP ...
MIB Browser免费版是一款专业的MIB浏览器,可以显示mib、oid、syntax、access、status等信息,通过查看mib相应对象的值实现对网络设备状态的监视,支持多种标准。软件绿色免安装,需要的朋友可以下载
"Broswer"是"browser"的拼写错误,指的是互联网浏览器,这是一种软件应用,用于访问、搜索和浏览互联网上的信息。浏览器的主要功能包括输入网址、加载网页、保存书签、管理历史记录等。常见的浏览器有Chrome、Fire...
BrowserFS(Browser File System)是一个开源项目,设计用于在浏览器环境中提供类似Node.js的文件系统接口。这个系统的核心目标是让Web应用可以在客户端处理文件,就像它们在服务器端使用Node.js时那样。通过...
MG-SOFT MIB Browser Professional Edition with MIB Compiler, MIB Explorer and Visual MIB Builder for Windows. Package Version 2018a (published 28-Dec-2017)
标题中的“从neo4j-broswer剥离出graph图表”指的是将Neo4j浏览器中的图形界面,特别是其数据可视化部分,独立出来进行更深入的定制和使用。这通常涉及到两个关键的技术领域:图形渲染和数据操作。在Neo4j中,图形...
此外,如果压缩包中的"broswer"文件包含了示例代码或其他资源,可以仔细研究这些文件,了解具体实现细节。例如,可能有自定义的URL处理器、设置网页参数或处理特定错误的代码。记得阅读和理解提供的代码,以便更好地...
#文件浏览器 使用Node和VueJS构建的文件浏览器和管理器。 用Exiftool提取的Medatata。 仅在Mac OS X上测试。 ##安装 克隆或下载此存储库 $ npm安装 $ CD应用程序 $节点服务器 如果出现错误,可能需要运行$ sudo...
"我的浏览器异步可插拔协议"是一个关于网络编程的主题,尤其在Windows环境中,它涉及到浏览器或其他应用程序如何处理网络通信,特别是如何实现非阻塞的、高性能的数据传输。Asynchronous Pluggable Protocol(简称...
【DJY-broswer 利用html做桌面软件】 HTML是一种标记语言,通常用于构建网页,但通过一些技术手段,我们可以将其转变为桌面应用程序。DJY-browser项目就是这样的一个实例,它利用HTML作为用户界面,结合JavaScript...
在本文中,我们将深入探讨如何在Visual C++ 6.0(简称VC6)环境下,利用ActiveX技术集成Internet Explorer(IE)浏览器组件进行开发。这个主题被命名为"VC6_IE_Broswer",暗示我们将关注如何在VC6中使用CWebBrowser2...
标题中的“Python-HomeAssistant集成可将您的浏览器变为可控制的实体以及成为一个音频播放器”表明这个项目是关于使用Python编程语言与Home Assistant智能家居平台进行整合,以实现通过浏览器来控制家居设备的功能,...
- 如果未安装,可以从Microsoft官方网站下载最新版本的MSXML6.0进行安装。 - 如果已安装但仍然存在问题,尝试卸载后重新安装。 2. **检查SQL Server安装**: - 审查SQL Server 2008的安装日志,查看是否有任何...
React键文件浏览器 基于文件夹的文件浏览器,由对象提供一个平面键控对象列表,由React提供支持。 现场演示 在此处查看实时演示: : 安装 使用npm安装软件包: npm install react-keyed-file-browser 然后要求并...