扶贫网站开发的目的是什么,阿坝网站制作,临沧网站搭建,做网站系统用什么语言【导读】前两天我采用技巧式方案基本实现大文件分片上传#xff0c;这里只是重点在于个人思路和亲身实践#xff0c;若在实际生产环境要求比较高的话肯定不行#xff0c;仍存在一些问题需要深入处理#xff0c;本文继续在之前基础上给出基于tus协议的轮子方案#xff0c;本… 【导读】前两天我采用技巧式方案基本实现大文件分片上传这里只是重点在于个人思路和亲身实践若在实际生产环境要求比较高的话肯定不行仍存在一些问题需要深入处理本文继续在之前基础上给出基于tus协议的轮子方案本打算再次尝试利用.NET Core实现此协议但在github上一搜索早在2016年就已有此协议对应的.NET和.NET Core方案并且一直更新到最近的.NET Core 3.x版本完全满足各位所需本文是我写出的一点demo。基于tus协议实现断点续传演示基于tus协议前端脚本关于此协议实现原理这里不做阐述请参照上述github地址自行了解本文只是给出.NET Core方案下的基本demo我们上传一个大文件然后通过进度显示上传进度以及对上传可暂停可继续专业点讲就是断点续传首先肯定是引入tus脚本和需要用到的bootstrap样式我们将进度条默认隐藏当上传时才显示所以我们给出如下HTML。div classform-horizontal stylemargin-top:80px;div classform-group idprogress-group styledisplay:none;div idsize/divdiv classprogressdiv idprogress classprogress-bar progress-bar-success progress-bar-animated progress-bar-striped roleprogressbararia-valuemin0 aria-valuemax100span idpercentage/span/div/div/divdiv classform-groupdiv classcol-md-10input namefile idfile typefile //div/divdiv classform-groupdiv classcol-md-offset-2 col-md-10input typesubmit idsubmit value上传 classbtn btn-success /input typebutton idpause value暂停 classbtn btn-danger /input typebutton idcontinue value继续 classbtn btn-info //div/div
/div
接下来就是使用引入的tus脚本也没什么太多要讲解的直接上代码这里稍微注意的是在如下元数据metadata属性对象定义给出实际文件名便于在后台最终将上传的文件转换为目标文件至少得知道文件扩展名对吧。script typetext/javascript$(function () {var upload;//上传$(#submit).click(function () {$(#progress-group).show();var file $(#file)[0].files[0];// 创建tus上传对象upload new tus.Upload(file, {// 文件服务器上传终结点地址设置endpoint: files/,// 重试延迟设置retryDelays: [0, 3000, 5000, 10000, 20000],// 附件服务器所需的元数据metadata: {name: file.name,contentType: file.type || application/octet-stream,emptyMetaKey: },// 回调无法通过重试解决的错误onError: function (error) {console.log(Failed because: error)},// 上传进度回调onProgress: onProgress,// 上传完成后回调onSuccess: function () {console.log(Download %s from %s, upload.file.name, upload.url)}})upload.start()});//暂停$(#pause).click(function () {upload.abort()});//继续$(#continue).click(function () {upload.start()});//上传进度展示function onProgress(bytesUploaded, bytesTotal) {var percentage (bytesUploaded / bytesTotal * 100).toFixed(2);$(#progress).attr(aria-valuenow, percentage);$(#progress).css(width, percentage %);$(#percentage).html(percentage %);var uploadBytes byteToSize(bytesUploaded);var totalBytes byteToSize(bytesTotal);$(#size).html(uploadBytes / totalBytes);}//将字节转换为Byte、KB、MB等function byteToSize(bytes, separator , postFix ) {if (bytes) {const sizes [Bytes, KB, MB, GB, TB];const i Math.min(parseInt(Math.floor(Math.log(bytes) / Math.log(1024)).toString(), 10), sizes.length - 1);return ${(bytes / (1024 ** i)).toFixed(i ? 1 : 0)}${separator}${sizes[i]}${postFix};}return n/a;}});/script
基于tus协议tusdotnet接下来进入后台首先安装对应tus协议实现包如下接下来则是添加tus中间件说白了就是对tus的配置各种配置都可满足你所需这里我只实现了文件上传完成后将上传文件转换为目标文件的处理紧接着将如下实现tus配置以单例形式注入即可private DefaultTusConfiguration CreateTusConfiguration(IServiceProvider serviceProvider)
{var env (IWebHostEnvironment)serviceProvider.GetRequiredService(typeof(IWebHostEnvironment));//文件上传路径var tusFiles Path.Combine(env.WebRootPath, tusfiles);return new DefaultTusConfiguration{UrlPath /files,//文件存储路径Store new TusDiskStore(tusFiles),//元数据是否允许空值MetadataParsingStrategy MetadataParsingStrategy.AllowEmptyValues,//文件过期后不再更新Expiration new AbsoluteExpiration(TimeSpan.FromMinutes(5)),//事件处理各种事件满足你所需Events new Events{//上传完成事件回调OnFileCompleteAsync async ctx {//获取上传文件var file await ctx.GetFileAsync();//获取上传文件元数据var metadatas await file.GetMetadataAsync(ctx.CancellationToken);//获取上述文件元数据中的目标文件名称var fileNameMetadata metadatas[name];//目标文件名以base64编码所以这里需要解码var fileName fileNameMetadata.GetString(Encoding.UTF8);var extensionName Path.GetExtension(fileName);//将上传文件转换为实际目标文件File.Move(Path.Combine(tusFiles, ctx.FileId), Path.Combine(tusFiles, ${ctx.FileId}{extensionName}));}}};
}/script
然后获取并使用上述添加的tus配置服务app.UseTus(httpContext Task.FromResult(httpContext.RequestServices.GetServiceDefaultTusConfiguration()));
在脚本中我们看到有个endpoint属性此属性表示上传到服务器的上传结点地址因为在上到服务器时我们可能需对此请求进行额外处理比如元数据中的文件名是否已提供等等所以我们在使用结点映射时添加对上述结点名称的映射如下endpoints.MapGet(/files/{fileId}, DownloadFileEndpoint.HandleRoute);
该映射第二个参数为RequestDelegate这个参数用过.NET Core的童鞋都知道这里我是直接拷贝该包的路由实现如下public static class DownloadFileEndpoint
{public static async Task HandleRoute(HttpContext context){var config context.RequestServices.GetRequiredServiceDefaultTusConfiguration();if (!(config.Store is ITusReadableStore store)){return;}var fileId (string)context.Request.RouteValues[fileId];var file await store.GetFileAsync(fileId, context.RequestAborted);if (file null){context.Response.StatusCode 404;await context.Response.WriteAsync($File with id {fileId} was not found., context.RequestAborted);return;}var fileStream await file.GetContentAsync(context.RequestAborted);var metadata await file.GetMetadataAsync(context.RequestAborted);context.Response.ContentType GetContentTypeOrDefault(metadata);context.Response.ContentLength fileStream.Length;if (metadata.TryGetValue(name, out var nameMeta)){context.Response.Headers.Add(Content-Disposition,new[] { $attachment; filename\{nameMeta.GetString(Encoding.UTF8)}\ });}using (fileStream){await fileStream.CopyToAsync(context.Response.Body, 81920, context.RequestAborted);}}private static string GetContentTypeOrDefault(Dictionarystring, Metadata metadata){if (metadata.TryGetValue(contentType, out var contentType)){return contentType.GetString(Encoding.UTF8);}return application/octet-stream;}
}
文件上传大小限制统一说明我们知道无论是.NET还是.NET Core对于文件上传大小都有默认限制大小这里对.NET Core中文件大小各种环境配置做一个统一说明如果你将.NET Core寄宿在IIS上运行那么请修改web.config配置文件大小限制system.webServersecurityrequestFiltering//若不配置默认是28.6兆requestLimits maxAllowedContentLength1073741824 //requestFiltering/security
/system.webServer
如果在开发环境默认使用IIS运行应用程序请通过如下根据实际情况配置文件上传大小services.ConfigureIISServerOptions(options {options.MaxRequestBodySize int.MaxValue;});
如果程序运行在Kestrel服务器那么请通过如下根据实际情况配置文件上传大小services.ConfigureKestrelServerOptions(options
{//若不配置默认是30兆没记错的话options.Limits.MaxRequestBodySize int.MaxValue;
});
如果是通过表单上传文件那么请通过如下根据实际情况配置文件上传大小services.ConfigureFormOptions(x
{x.ValueLengthLimit int.MaxValue;//如果不配置默认是128兆没记错的话x.MultipartBodyLengthLimit int.MaxValue; x.MultipartHeadersLengthLimit int.MaxValue;
});
为了更好体验可以再加上当前网络宽带情况或剩余多少分钟更详细内容请参考https://github.com/tusdotnet/tusdotnet 、https://github.com/tus/tus-js-client关于大文件上传处理到此结束希望对那些苦苦寻找最终解决方案而无助的童鞋们提供最佳轮子谢谢。