您当前的位置: 首页 >  .net

寒冰屋

暂无认证

  • 5浏览

    0关注

    2286博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

在TypeScript和ASP.NET Core中处理文件上传和受保护的下载

寒冰屋 发布时间:2020-03-24 21:50:31 ,浏览量:5

目录

介绍

背景

使用代码

注册您的API

main.ts

api-plugin.d.ts

上传文件

提交文件

API服务方法

ASP.NET Core API方法

下载文件

客户端API下载

保护上传的文件

介绍

我最近在一个需要上传和下载文件的网站上工作。似乎对某些人来说这是一个痛苦的地方,所以我想我应该写一篇小文章(因为我的上一篇文章已经太久了,已经过期很久了),既为我自己的后代,也为其他东西。

背景

我正在构建的应用程序是销售数字产品的商店。前端全部用VueJS编写,带有一个ASP.NET Core后端API,用于提供文件和SPA。

使用代码

该代码是很容易解释的,因此,我将仅简要介绍每个模块的功能,而不是详细介绍所有内容并弄乱该主题。

注册您的API main.ts

导入您的api模块

import api from './services/api'; -- this is my sites api
...
Vue.prototype.$api = api;
api-plugin.d.ts

将$api变量附加到Vue并为其指定Api类型。

import { Api } from './services/api';
 
 declare module 'vue/types/vue' {
     interface Vue {
         $api: Api;
     }
}

export default Api;
上传文件

在我的VueJS组件中,我在data()对象内部创建了一个变量,用于保存要发送到服务器的文件。

files: new FormData(),

我添加了一个处理程序方法来响应向上传文件添加文件的用户

handleFileUpload(fileList: any) {
    this.files.append('file', fileList[0], fileList[0].name);
},

Vue组件模板包含文件输入元素

提交文件

然后,当用户在您的UI上执行触发上传的操作时,我将调用我的API。

this.$api.uploadFile(this.files)
    .then((response: ) => {
        this.hasError = false;
        this.message = 'File uploaded';
    }).catch((error) => {
        this.hasError = true;
        this.message = 'Error uploading file';
    });
API服务方法

上面在tern中显示的组件方法在我的API服务上调用此方法。

public async uploadFile(fileData: FormData): Promise {
    return await axios.post('/api/to/your/upload/handler', fileData, { headers: { 'Content-Type': 'multipart/form-data' } })
        .then((response: any) => {
            return response.data;
        })
        .catch((error: any) => {
            throw new Error(error);
        });
}
ASP.NET Core API方法

该方法中的代码会根据您自己的要求而有很大的不同,但是基本结构看起来像这样。

[HttpPost("/api/to/your/upload/handler")]
[Consumes("multipart/form-data")]
public async Task UploadHandler(IFormCollection uploads)
{
    if (uploads.Files.Length  {
            const disposition = response.headers['content-disposition'];
            let fileName = '';

            if (disposition && disposition.indexOf('attachment') !== -1) {
                const filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
                const matches = filenameRegex.exec(disposition);
                if (matches != null && matches[1]) {
                    fileName = matches[1].replace(/['"]/g, '');
                }
            }

            const fileUrl = window.URL.createObjectURL(new Blob([response.data]));
            const fileLink = document.createElement('a');
            fileLink.href = fileUrl;
            fileLink.setAttribute('download', fileName);
            document.body.appendChild(fileLink);
            fileLink.click();
        })
        .catch((error: any) => {
            throw new Error(error);
        });
}

这将设置客户端下载并打开本地用户常规浏览器文件保存对话框。

保护上传的文件

鉴于上面的代码是“手动”处理文件下载和上传的,因此可以认为,浏览器HTML中文件的简单URL不是理想的情况。在我的例子中,上传的文件放在我要处理下载的目录中。

为了保护此“下载”目录,我在该StartUp.cs Configure方法中将少量逻辑映射到.NET Core IApplicationBuilder实例。这将拦截对此URL的任何请求并发送401响应。

app.Map("/downloads", subApp => {
    subApp.Use(async (context, next) =>
    {
        context.Response.StatusCode = StatusCodes.Status401Unauthorized;
    });
});

任何试图访问该downloads目录中文件的人都将被引导,浏览器将收到服务器的错误响应。

我希望您在这种方法的简短描述中能找到一些用处。

关注
打赏
1665926880
查看更多评论
立即登录/注册

微信扫码登录

0.0962s