.NET Core C#系列之UseStaticFiles静态文件高级用法

问题背景:在项目目录下录制了一批mp4视频文件。我通过ip+端口号+MP4的路径返回给api接口调用者。

{
  playurl:"localhost:7089/1.mp4",
  playurl:"localhost:7089/2.mp4"
  playurl:"localhost:7089/3.mp4",
  playurl:"localhost:7089/4.mp4"
}

web界面通过视频标签,可以进行页面上的播放,但是就是点击下载的时候,

2d453229d50ff111f37f75ce7c3633f2.png

浏览器会在开启一个tab页面,然后播放视频。视频的右下角有一个下载的功能。再开启一个tab再下载,有点影响用户体验。网上我也搜了前端可以直接处理这种情况,但是前端同事因工作量庞大,没有时间处理,于是鉴于这样的一种情况。我被逼无奈,于是使用后端技术来干预前端。

在自我苦恼纠结中,甚至差点抑郁(夸张了,嘿嘿),使用xiaofeng降龙十八掌大招,我对UseStaticFiles这个静态扩展类做了近一步的研究。

在写WebAPI项目中,会创建一个wwwroot文件夹,在这个里面写一些静态文件。例如html、zip、excel、MP4、json、txt等静态文件。

然后在Configure里面使用静态文件类。

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
       if (env.IsDevelopment())
       {
          ....
       }
      ....
      app.UseStaticFiles();    
      ....  
}

用户在浏览器输入 localhost:7089/1.mp4,回车之后,即可在页面上看见一个视频。

48db439c517bc7a67d31d6c9ffc81940.png

231795354cdb458a72e24e505bf27d7f.png

有时这个地址需要给第三方的客户使用,会遇到静态文件跨域问题。

此时我们在代码里使用

app.UseCors( 
                    builder => builder.AllowAnyOrigin()
                        .AllowAnyHeader()
                        .AllowAnyMethod()
                );

是没有效果的,这个app.UseCors  跨域是c# 代码的跨域,我们wwwroot文件夹的文件属于静态代码,这个是控制不了的。

或者用户输入 localhost:7089/1.mp4,是想直接下载,并不想播放。

这个时候,遇到静态文件跨域、静态文件直接下载(输入路径不想在web界面上直接浏览观看)此时就要用到我们UseStaticFiles静态文件高级操作了。

静态文件解决跨域代码如下:

app.UseStaticFiles(new StaticFileOptions
                    {
                        OnPrepareResponse = (c) =>
                        {
                            c.Context.Response.Headers.Add("Access-Control-Allow-Origin", "*");
                            c.Context.Response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS, TRACE, HEAD, PATCH");
                            c.Context.Response.Headers.Add("Access-Control-Allow-Headers", "*");                            
                        }           
                    });

如果用户想直接下载MP4、json文件,并不想在线浏览。

地址:localhost:7089/1.mp4

我们可以在地址后面加上后缀,便于我们进行识别过滤。

localhost:7089/1.mp4?f=save

我在路径后面加了?f=save,当用户浏览静态文件时,想下载,我通过这个标识来做判断。当f=save,你可以自定义。例如 download=true等...

静态文件直接下载,上代码:

app.UseStaticFiles(new StaticFileOptions
                    {                        
                        OnPrepareResponse = (c) =>
                        {
                             var request = c.Context.Request;
                             var response = c.Context.Response;
                             var f = request.Query["f"].ToString();
                             if (f.Equals("save", StringComparison.OrdinalIgnoreCase))
                             {
                                  response.Headers.Add("Content-Disposition", "attachment; filename=" + Path.GetFileName(request.Path));
                             }
                        }           
                    });

其实核心代码就是,用户请求我们的地址,我们在响应头部加上 下载的标识,这个"Content-Disposition" 其实是告诉浏览器,我要下载文件,我不想在线浏览。

加完这句话,浏览器输入:localhost:7089/1.mp4?f=save

3fe1d7c7b4ab4941bd91a0a7fc8bec81.png

然后浏览器就会弹出下载的文件。下载的快慢和网络/文件的大小有关系。

85ca540e02e7a335aef473a04784e7e5.png

如果下载地址有跨域问题,则把上面的代码合在一起就行了。

全部代码如下:

app.UseStaticFiles(new StaticFileOptions
                    {
                        OnPrepareResponse = (c) =>
                        {
                            c.Context.Response.Headers.Add("Access-Control-Allow-Origin", "*");
                            c.Context.Response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS, TRACE, HEAD, PATCH");
                            c.Context.Response.Headers.Add("Access-Control-Allow-Headers", "*");
                            var request = c.Context.Request;
                             var response = c.Context.Response;
                             var f = request.Query["f"].ToString();
                             if (f.Equals("save", StringComparison.OrdinalIgnoreCase))
                             {
                                  response.Headers.Add("Content-Disposition", "attachment; filename=" + Path.GetFileName(request.Path));
                             }                            
                        }           
                    });

还有更高级的用法,例如:

运行的netcore代码路径:/root/projectWeb/

linux视频路径:

"/storage/projectWeb/VideoFile/"

Windows视频路径:

"C:\\Users\\autoChang\\Downloads"

我们在上面代码的基础上加一行

RequestPath = new PathString("/VideoFile")

然后对下面的路径做下转换

new PhysicalFileProvider("/storage/projectWeb/VideoFile/"),//这个路径也可以自定义

linux环境整体代码如下:

app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider("/storage/projectWeb/VideoFile/"),
    OnPrepareResponse = (c) =>
    {
        c.Context.Response.Headers.Add("Access-Control-Allow-Origin", "*");
        c.Context.Response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS, TRACE, HEAD, PATCH");
        //c.Context.Response.Headers.Add("Access-Control-Allow-Credentials", "true");
        c.Context.Response.Headers.Add("Access-Control-Allow-Headers", "*");
        var request = c.Context.Request;
        var response = c.Context.Response;
        var f = request.Query["f"].ToString();
        if (f.Equals("save", StringComparison.OrdinalIgnoreCase))
            response.Headers.Add("Content-Disposition", "attachment; filename=" + Path.GetFileName(request.Path));
    },
    RequestPath = new PathString("/VideoFile")
});

window环境整体代码如下:

app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider("C:\\Users\\98263\\Downloads"),
    OnPrepareResponse = (c) =>
    {
        c.Context.Response.Headers.Add("Access-Control-Allow-Origin", "*");
        c.Context.Response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS, TRACE, HEAD, PATCH");
        //c.Context.Response.Headers.Add("Access-Control-Allow-Credentials", "true");
        c.Context.Response.Headers.Add("Access-Control-Allow-Headers", "*");
        var request = c.Context.Request;
        var response = c.Context.Response;
        var f = request.Query["f"].ToString();
        if (f.Equals("save", StringComparison.OrdinalIgnoreCase))
            response.Headers.Add("Content-Disposition", "attachment; filename=" + Path.GetFileName(request.Path));
    },
    RequestPath = new PathString("/VideoFile")
});

通过netcore运行的ip+端口号+路径 也可以访问视频的地址:

localhost:7089/VideoFile/1.mp4

好了,本期分享就到这里吧~

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值