续上一篇 (http://blog.csdn.net/querw/archive/2009/08/24/4477182.aspx) 谈谈在APS.NET中如何控制文件下载.
设计目的和要求
假设这么一个应用场景:
一个主机,上面存有许多文件资料,有各种文件格式.(PDF, DOC, EXE ... 等等).
该主机上运行一个ASP.NET网站, 用户注册,并付费之后允许他/她下载资料.
文件是放在IIS服务器上的, 如果用户知道具体路径那么他是可以随时下载的. (在没有或者不能设置访问权限的情况下.)
如果直接把下载路径发送给付费用户,肯定是行不通的,会被散播出去. 所以不能把让客户端得知具体路径,文件内容由 ASP.NET 服务器页面读取后发送给客户端.
我要做的就是: 编写一个ASP.NET 页面服务器代码, 读取指定文件,并发送给客户 .
总体思路
.net 里, 有2个函数可以用来发送文件 Response.WriteFile 和 Response.TransmiteFile
它们的主要区别是: WriteFile 是先把文件内容读取到服务器缓冲,然后再发送到客户端. 所以对于大文件,会造成服务器很大的压力.
一般用来处理小文件,比如,发送给 excel 报表之类的. TransmiteFile 不缓冲数据, 直接抛给客户端, 所以可以用来发大文件.
( 我采用 TransmiteFile 来实现.)
具体实现
1. 给客户一个链接,形如 http://xxxx/downloads.aspx?Key=ABCD123456
2. 在downloads.aspx的服务器代码中, 通过Key的值,查询数据库,得到服务器上的真实文件路径. 这个时候,控制权在 downloads.aspx, 所以可以编写复杂的控制功能, 比如看看用户有没有登录,有没有付费之类的,从而避免外部盗链.
3. 得到文件路径后,调用 Response.TransmiteFile 发送文件给客户端.
4. 因为给客户的链接里没有任何文件名的信息, 所以要在HTTP响应头里添加一句,告诉客户端文件名: Response.AddHeader("Content-Disposition", "attachment; filename=/"" + 你的文件名 + "/""); (如果要支持中文,要考虑编码的问题, 我这里不说,不是我们的主题.)
5. 如果是一个大文件, 比如1G, 不支持断点续传,是没有意义的. 那么如何实现呢?
(1) 要让客户端知道我们的服务器支持断点续传, 要在HTTP响应头中包含 Accept-Ranges: bytes 和 ETag: "XXXX".
ETag 是一个文件的标识, 供客户端判断它请求的是同一个文件, ETag 的内容在HTTP规范里并没有具体要求,只要保证在同一个服务器上,同一个文件有相同的ETag 就行了, 一般就根据文件名和最后修改时间生成一个字符串就可以了.
代码示例:
Response.AddHeader("Accept-Ranges", "bytes"); // 断点续传控制.
Response.AddHeader("ETag", "/"" + strETag + "/""); // 允许断点续传
(2) 要处理客户端请求中的 "Range" 字段. 一般格式是这样: Range: bytes=1234- 或者 Range: bytes=1234-12345
分别表示从地1235个字节开始下载和下载第1235到第12346个字节之间的数据.
服务器首先要添加 Content-Range 响应头, 然后用 TransmiteFile 发送指定的数据.
代码示例:
Response.StatusCode = 206;
Response.
Godaddy服务器上关于ASP.NET网站建设一些经验 - 断点续传下载 (二)
最新推荐文章于 2024-07-14 22:05:39 发布