【问题标题】:.NET Web Service - download file and force browser to open it.NET Web 服务 - 下载文件并强制浏览器打开它
【发布时间】:2013-08-29 14:57:22
【问题描述】:

我有一个创建文件并将其提供给浏览器的 Web 方法。

在 Chrome 中,文本文件只是下载。

在 IE9 中,浏览器询问我是否要打开或保存文件。

我想做的是让浏览器自动打开文件(在该文件类型的默认程序中)

代码:

        [WebMethod]
        [ScriptMethod(UseHttpGet = true)]
        public void Test(string docNum, string docVersion)
        {
            var response = Context.Response;
            response.ContentType = "application/octet-stream";
            response.AppendHeader("Content-Disposition", "attachment; filename=" + docNum + ".txt");
            Byte[] stream = System.Text.Encoding.ASCII.GetBytes("docNum + "," + docVersion);
            response.OutputStream.Write(stream, 0, stream.Length);
            response.Flush();
        }

我通过以下方式唤起它:

http://localhost:12345/Services/Foo.asmx/Test?docNum=123456789&docVersion=1

如何让浏览器只打开文件?

【问题讨论】:

  • 您无法强制打开外部程序。如果可以的话,这将是一个巨大的安全风险。
  • @Juhana - 同意;但是,我并不是要强制打开外部程序。我试图让浏览器自动打开文件。我们肯定有链接让浏览器自动打开文件,而不是要求用户选择打开或保存。
  • 是的,你不能这样做。自动打开程序完全取决于浏览器和用户。
  • 我们有一个旧的冷融合服务做同样的事情,IE 不会询问用户是否应该打开或保存文件。它只是打开它。当我使用此服务时,IE 会询问我。
  • 您能具体说明一下文件类型吗?我看到您将文件输出为“八位字节流”。这是一个非常通用的类型。如果您希望浏览器打开 jpg 或 pdf 或 xls,则最好使用更具体的 mime 类型。那么,您输出的是什么类型?

标签: .net web-services asmx


【解决方案1】:

可能与您的浏览器配置打开的文件类型更相关。

如果浏览器不知道如何打开某些类型的文件,它会提示您下载它

另一件事是您为 TXT 文件指定了 octect-stream

Content-Type: application/octet-stream
Content-Disposition: attachment;filename=\"My Text File.txt\"

这实际上会强制浏览器下载此处提到的内容

What content type to force download of text response?

【讨论】:

  • 文件类型相同。我们有一个旧的 ColdFusion 应用程序可以做同样的事情,并且文件会自动下载。
  • 实际上第二次认为它是不同的文件类型。 CF 程序正在获取实际文档,其中此 Web 服务正在返回专有文件类型,该文件类型由专有程序打开并获取实际文档,因此可能是它。
【解决方案2】:

如果您希望浏览器打开 jpg、pdf 或 xls,您需要在“ContentType”标题中指定正确的 mime 类型。例如,现在您将所有内容输出为“八位字节流”,这是非常通用的。浏览器无法猜测哪个程序会打开这样的泛型类型。但是,如果是 xls,您可以使用“application/vnd.ms-excel”的 ContentType。

这是一个 SO 答案,它指向用于查找可能的 mime 类型的大量资源列表:https://stackoverflow.com/a/7192429/283895

【讨论】:

  • 如果我知道应用程序名称,但它不是标准的 mime 类型,我是否可以告诉浏览器尝试使用该应用程序打开它?
  • 文件扩展名是在操作系统中注册的,所以它知道如何打开它。但是,据我所知,这种文件类型没有 Mime 类型。我卡住了吗?我可以对我的服务器代码或浏览器设置进行任何修改以使其尝试自动打开此文件类型吗?
  • 自从你在你的操作系统上注册了你的文件扩展名,你已经很接近了。您还需要为该扩展创建一个 ContentType。我通常通过快速注册表黑客来做到这一点。示例:使用 RegEdit 查看“HKEY_CLASSES_ROOT\.pdf”。您可以看到有一个名为“Content Type”的键,其值为“application/pdf”。那是 .pdf 的 ContentType。您可以自己制作“application/kralco626”并将其设置为 ContentType。您必须在每台机器上执行此操作(或让您的 exe 设置)。然后你可以从你的网络服务器输出那个 ContentType。
  • (安全信息)通常,建议人们远离注册表,我会觉得很奇怪。但是,由于您已经在操作系统中注册了文件扩展名,这意味着您已经完成了 90% 的注册表调整。你只是错过了最后一件事。
【解决方案3】:

如果客户端计算机知道如何打开文件扩展名,您实际上可以这样做。 我已经让它在 IE9

中工作

假设您有一个文件扩展名.xyz

Pre-Rec: 客户端计算机应注册文件扩展名.xyz,以使用您希望打开的每个程序打开。如何在这里:http://windows.microsoft.com/en-us/windows-vista/change-which-programs-windows-uses-by-default

步骤 1: 在 IIS 中设置一个新的 MIME 类型,其属性为文件扩展名 = .xyz 和 MIME 类型 = `application/xyz" 如何在此处:http://technet.microsoft.com/en-us/library/cc725608(v=ws.10).aspx

第 2 步:在代码中将 MIME 类型设置为您刚刚创建的类型,并将 Content-Disposition 更改为“内联”:

response.ContentType = "application/xyz";
"Content-Disposition", "inline;

.xyz文件类型的工作示例

        [WebMethod]
        [ScriptMethod(UseHttpGet = true)]
        public void Test(string docNum, string docVersion)
        {
            var response = Context.Response;
            response.ContentType = "application/xyz";
            response.AppendHeader("Content-Disposition", "inline; filename=" + docNum + ".xyz");
            Byte[] stream = System.Text.Encoding.ASCII.GetBytes(docNum + "," + docVersion);
            response.OutputStream.Write(stream, 0, stream.Length);
            response.Flush();
        }

这在 IE9 中对我有用。

我已经在 Chrome 中尝试过,但它不起作用,它自动下载了文件,虽然我没有在 Chrome 中使用任何设置。 如果有人有跨浏览器的解决方案,我会很感兴趣。

【讨论】:

    猜你喜欢
    • 2011-06-19
    • 2017-12-27
    • 2013-04-13
    • 1970-01-01
    • 2013-10-15
    • 2015-01-25
    • 2017-06-03
    • 1970-01-01
    • 2016-07-15
    相关资源
    最近更新 更多