我正在尝试编写 MVC 端点,该端点可以选择将内容配置设置为内联或附件,以便在新的浏览器选项卡中显示文件(pdf)或下载它。 UI 允许用户选择他们想要打开文件的方式(不是我的设计 - 无法更改它的这方面)。
请注意,这在 Chrome/Edge 中正如预期的那样工作。
在 Firefox 中,PDF 的应用程序设置似乎胜过内容配置。有没有可靠的方法让 Firefox 尊重内容处置?最好是一种可以在浏览器的普通安装中工作的方式,这样最终用户不需要对其进行任何修改即可工作。
这是我用来设置响应的代码(类派生自 ApiController):
var response = Request.CreateResponse(System.Net.HttpStatusCode.OK);
response.Content = new PushStreamContent((stream, content, context) =>
{
dispatcher.Dispatch(request, stream);
}, new MediaTypeHeaderValue(MediaTypeNames.Application.Pdf));
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue(contentDisposition)
{
FileName = $"{auto_generated_fileName}.pdf",
};
response.Headers.CacheControl = new CacheControlHeaderValue()
{
NoCache = true,
NoStore = true
};
return response;
我们也在我们的网络应用程序中注意到了这个问题。该网络应用程序有一个下载按钮,可让用户下载 PDF 文件。 Firefox 在当前选项卡中显示 PDF 文件,这有效地杀死了 web 应用程序。
经过一番研究,这似乎是一个有意为之的功能,请参阅 Firefox 98 的发行说明:
当您在 Firefox 首选项设置中将应用程序设置为打开特定类型的文件时,这些文件将自动打开,甚至是由带有“内容处置:附件”的网站提供的文件。这同样适用于默认设置为在 Firefox 中打开的 PDF 文件。这是对 bug 453455 的修复。
就我个人而言,虽然我可以理解一些用户可能希望针对表现不佳的网页使用此功能,但这对于表现良好的网络应用程序来说是一个问题。
在锚点上设置 download 属性似乎也不起作用,Firefox 仍然显示内联文件(使用 Firefox 99.0 测试)
据我所知,如果浏览器不允许,您不能强制浏览器下载文件。其他网络应用程序(例如 OwnCloud 或 Google Drive)也存在同样的问题 - 如果您右键单击 Google Drive 中的 PDF 文件,然后单击
Dowload
,Firefox 仍会内联打开 PDF 文件,而 Chrome 会下载它。
目前,您能做的最好的事情似乎是在新选项卡中打开文件,以防止网络应用程序或网页被下载的文件替换(这也是 Google Drive 似乎正在做的事情)。您可以在新选项卡或窗口中打开下载,例如通过 <a>
链接上的
target 属性或通过
<button>
元素上的 formtarget 属性。
在尝试找到与OP相同问题的解决方案后,我找到了@blutorange的答案。然而,就在我到达这里之前,我在 2013 年偶然发现了这个答案 - https://stackoverflow.com/a/16515146,它建议将
Content-Type
标头设置为 application/octet-stream
,而不是 application/pdf
.
我尝试了这个解决方案,你知道吗 - 它有效! PDF 会自动在 Firefox 中的新选项卡中打开,但至少它不会替换我的应用程序的选项卡,所以耶! Chrome 似乎也不介意,我计算机上的 PDF 查看器也将这些文件识别为 PDF。
现在,这可能不是对我们面临的问题最“正确”的解决方案,但它是强制打开新选项卡的替代方法。
浏览器现在忽略 Content-Type: application/octet-stream 和 Content-Disposition“attachment;”参数。
浏览器查看 Content-Disposition 中的文件扩展名,以确定是否应在浏览器窗口中打开文件,或弹出一个文件对话框,询问用户是否以及要将文件保存到何处。
如果您想强制浏览器打开文件对话框,那么您可以删除文件扩展名,这会迫使浏览器谦虚并请求用户许可。