解决asp.netcore 3.1静态文件中exe在谷歌类浏览器下载时出现乱码页面的问题

谷歌类浏览器下载asp.netcore3.1静态文件时不能正常保存的问题解决

问题现象:

用谷歌类浏览器访问asp.netcore的静态exe文件不出现保存对话框,而是直接打开一个乱码页面,在其它浏览器中没有遇到这样的问题。

问题环境:
asp.netcore3 + google chrome / edge

解决过程记录:

问题思考:
  • 首先浏览器要打开文件需要识别访问到的文件类型,直接在页面显示而不是保存说明返回的类型是需要它直接显示;
  • 也就是说显示与否是由获取到的Content-Type来决定的,那么基本可以服务器返回的Content-Type对于它来说是一个不正确的值。
验证:
  使用 Fildder2 工具也可以完成此过程。
  • 通过F12打开“开发者工具”,到“网络”选项卡;
  • 访问一次 exe 的链接;
  • 查看链接的Response头信息:
    exe文件响应头,没有 Content-Type字段
    从结果上看 压根没有 Content-Type 这个头。😂
解决问题
通过以上方法已经验证了造成此问题的原因是服务器没有返回Content-Type头,说明服务器不认识exe类型的文件,到代码里验证一下。	
  • 查看服务器程序开户静态文件的代码处。
app.UseStaticFiles(new StaticFileOptions()
            {
                ServeUnknownFileTypes = true,
            });
这里开启了 ServerUnknownFileTypes 。
现在我们关闭 ServerUnknownFileTypes 
app.UseStaticFiles(new StaticFileOptions()
            {
                ServeUnknownFileTypes = false,
            });
  • 再访问一次 exe 文件的链接,发现已经不能正确访问了,返回的404
    服务器关闭未知类型静态文件后,访问exe文件返回404
  • 查看 StaticFileOptions ,里面两个属性
public IContentTypeProvider ContentTypeProvider { get; set; }
public string DefaultContentType { get; set; }

默认的StaticFileOptions对象

经测试 这两个属性默认都是null
那么接下来在这两个属性上面想办法就行了。

  1. 方法一: 通过 ContentTypeProvider 解决:
app.UseStaticFiles(new StaticFileOptions()
            {
                ServeUnknownFileTypes = true,
                ContentTypeProvider=new Microsoft.AspNetCore.StaticFiles.FileExtensionContentTypeProvider(new System.Collections.Generic.Dictionary<String, String> { { ".exe", "application/octet-stream" } })
            });

现在验证一下结果
访问 exe 文件,可以正常下载保存了。
Edge提示保存文件
再访问一下静态文件夹里的html页面
静态html页面不能正常显示了,以文本文件显示了
再看请求返回的文件头,发现没了 Content-Type

html页面没有了 Content-Type
这是因为上面设置的文件类型只包含了 exe 的定义,没有了其它类型,asp.netcore将除exe外的其它静态文件都什么意思不可识别的类型了。

ContentTypeProvider 被覆盖,让程序只认exe类型的文件,其它类型都为不可识别的类型。
此方法可以配合 ServeUnknownFileTypes = false 让客户端只能访问指定类型文件的功能。
  1. 方法二: 通过直接给Header加Content-Type解决
        app.UseStaticFiles(new StaticFileOptions()
        {
            ServeUnknownFileTypes = true,
            OnPrepareResponse = ctx =>
            {
                var headers = ctx.Context.Response.Headers;
                if (ctx.File.Name.ToLower().EndsWith(".exe"))
                    headers.Append("Content-Type", "application/octet-stream");
            }
        });

在浏览器访问一下exe文件,可以正常下载保存
再访问一下html页面,也可以正常显示。

此文件可以重定义某个类型文件的 Content-Type
  1. 方法三: 使用 DefaultContentType 属性
app.UseStaticFiles(new StaticFileOptions()
            {
                ServeUnknownFileTypes = true,
                DefaultContentType= "application/octet-stream"
            });

分别访问exe文件和html文件,exe可以正常保存,html页面也可以正常显示。

此方法可以让服务器将所有不识别的文件类型都以 ContentType 返回给浏览器。

以上三种方法可以灵活配置,实现不同的需求。


👨问题解决完毕!!😃😃😃😃😃

🆙🆙🆙🆙

aspnetcore 仓库的源码也确实没有发现 exe 的定义。
FileExtensionContentTypeProvider仓库源码地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值