我浏览了你的其他问题,我只是想确保我们清楚一些事情。(如果这里有什么是盲目的,请原谅我,我无意侮辱,我只是想确保我们在同一页上。)
首先,客户端和服务器。任何服务器端都在用户帐户的上下文中运行,并且与运行它的机器相关。如果您使用服务器端代码说“将其保存到桌面”,那么这是服务器的本地进程的桌面,几乎没有任何意义。但是,如果您正在模拟登录用户,这可能会起作用,除非您将其保存到服务器上登录用户的桌面。如果客户端和服务器在同一台机器上运行并且您正在模拟客户端,那么这实际上可能完全有效。也许。
其次,右键单击,另存为。当您右键单击链接时,您正在调用浏览器的内置专有菜单系统。该系统是特定于浏览器和/或操作系统的,并且没有在任何规范中定义。在 90 年代,您可能已经能够使用 VBScript 来“发送密钥”并让 Internet Explorer “单击”该链接,但那些日子早已一去不复返了。与此最接近的现代等价物是编写一个我想您不想做的插件(并且将是浏览器和/或特定于操作系统的)。
三、MIME类型。一般来说,每个 HTTP 响应都包含一个 MIME 类型,它指定服务器发送字节的意图。text/html
其中包括和之类的东西application/pdf
。当服务器端代码 (ASP.Net) 没有被调用时,例如图像和 CSS 等静态文件,甚至是 PDF 等预生成文件,服务器 (IIS) 在列表中查找文件扩展名以确定什么要发送的 MIME 类型。在客户端,浏览器使用 MIME 类型来确定要执行的操作。如果是text/html
它(可能)呈现 HTML。如果是,application/pdf
那么浏览器会查看它的MIME 类型列表,以查看是否有任何应用程序注册了该 MIME 类型。大多数现代浏览器都有一个内置的 PDF 渲染器,因此浏览器只需将字节传递给它进行渲染。如果浏览器不知道那个 MIME,它可能会询问操作系统它是否知道它并且有一个可用的注册处理程序,如果有,它会通过它。如果这一切都失败了(可能是因为像我这样的用户禁用了特定的 MIME 类型),那么浏览器要么只是将这些字节放入“下载”文件夹,它会尝试将这些字节解释为文本或提示保存。
根据HTTP 规范(19.5.1 第 3 段),深入了解最后一个,如果您发送一个 MIME 类型以及thenapplication/octet-stream
的标头Content-Disposition: attachment; filename="fname.ext"
暗示的建议是用户代理不应该显示响应,而是直接输入“将响应另存为...”对话框。
这就是你最终想要达到的目标,对吧?
在您的情况下,单击 PDF 链接会绕过 ASP.Net,而 IIS 只是查找文件并将application/pdf
MIME 类型连同它一起发送。一种解决方法是从系统中注销PDF 文件扩展名。然而,这可能不是最便携的解决方案。同样,您也可以将文件扩展名更改为application/octet-stream
,然后您(可能)会看到“另存为”对话框。
我认为强制“另存为”对话框的最佳选择是创建某种服务器端的处理程序,该处理程序将 MIME 类型和 Content Disposition 标头强制放入流中,然后传递文件的原始字节。您可以通过多种方式执行此操作,可能使用(这里IHttpHandler
可能更好)或者可能仅使用检查查询字符串的单个 ASPX 页面。您将需要执行一些额外的安全措施,并且一定要确保文件名中不允许出现类似路径的字符和命令。