目录
介绍
背景
使用代码
注册您的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目录中文件的人都将被引导,浏览器将收到服务器的错误响应。
我希望您在这种方法的简短描述中能找到一些用处。