js上传多个文件到asp.net core,并实时转存到阿里云oss
有时候,为了追求便利性,我们可能会让前端直接将文件上传到阿里云OSS,然后将URL提交给ASP.NET。然而,这种做法意味着前端需要拥有OSS的访问密钥,而将密钥存放在前端,无疑增加了被破解的风险。因此,最安全的做法仍然是由服务器端负责上传文件到OSS。
接下来,我将演示如何实现分块上传到服务器的过程,而且在这个过程中,服务器并不保存任何分块,而是直接将分块上传到OSS。
服务器端
asp.net 引用 nuget 包:
JMS.FileUploader.AspNetCore
Aliyun.OSS.SDK.NetCore
实现一个oss的 IUploadFilter , 把接收到的分块数据,实时传到oss
[UploadFilterDescription("Aliyun")]
public class AliyunUploadFilter : IUploadFilter
{
const string BucketName = "<your-bucket-name>";
const string OssEndpoint = "<your-oss-endpoint>";
const string AccessKeyId = "<your-accessKeyId>";
const string AccessKeySecret = "<your-accessKeySecret>";
string _uploadId;
string _ossUploadId;
string _objectKey;
OssClient _ossClient;
public async Task OnUploadBeginAsync(HttpContext context, string uploadId, string fileName, long fileSize, int fileItemIndex)
{
_uploadId = uploadId;
_objectKey = $"file{fileItemIndex}.zip";
_ossClient = new OssClient(OssEndpoint , AccessKeyId , AccessKeySecret );
var ret = _ossClient.InitiateMultipartUpload(new InitiateMultipartUploadRequest(BucketName, _objectKey));
if (ret.HttpStatusCode != System.Net.HttpStatusCode.OK)
throw new Exception(ret.HttpStatusCode.ToString());
_ossUploadId = ret.UploadId;
}
public async Task OnReceivedAsync(HttpContext context, Stream inputStream, long position, int size)
{
var data = new byte[size];
await inputStream.ReadAtLeastAsync(data, size);
using var ms = new MemoryStream(data);
var num = (int)(position / 102400) + 1;
var ret = _ossClient.UploadPart(new UploadPartRequest(BucketName, _objectKey, _ossUploadId) {
InputStream = ms,
PartSize = size,
PartNumber = num
});
if (ret.HttpStatusCode != System.Net.HttpStatusCode.OK)
throw new Exception(ret.HttpStatusCode.ToString());
}
public async Task<string> OnUploadCompletedAsync(HttpContext context)
{
for (int i = 0; i < 3; i++) // 如果发生错误,最多尝试3次
{
try
{
// 列出所有分块。
var listPartsRequest = new ListPartsRequest(BucketName, _objectKey, _ossUploadId);
var partList = _ossClient.ListParts(listPartsRequest);
// 创建CompleteMultipartUploadRequest对象。
var completeRequest = new CompleteMultipartUploadRequest(BucketName, _objectKey, _ossUploadId);
// 设置分块列表。
foreach (var part in partList.Parts)
{
completeRequest.PartETags.Add(new PartETag(part.PartNumber, part.ETag));
}
// 完成上传。
var ret = _ossClient.CompleteMultipartUpload(completeRequest);
if (ret.HttpStatusCode != System.Net.HttpStatusCode.OK)
throw new Exception(ret.HttpStatusCode.ToString());
//设置访问权限
_ossClient.SetObjectAcl(BucketName, _objectKey, CannedAccessControlList.PublicRead);
//返回下载的url路径
return ret.Location;
}
catch (Exception)
{
if (i == 2)
{
throw;
}
else
{
Thread.Sleep(3000);
}
}
}
return null;
}
public void OnUploadError()
{
}
}
然后注册这个 filter :
services.AddFileUploadFilter<AliyunUploadFilter>();
启用上传组件:
app.UseJmsFileUploader();
controller里面写一个最终的业务处理函数
[ApiController]
[Route("[controller]/[action]")]
public class MainController : ControllerBase
{
[HttpPost]
public string Test([FromBody] object body)
{
var customHeader = Request.Headers["Custom-Header"];
//临时文件路径
var filepath = Request.Headers["FilePath"];
//文件名
var filename = Request.Headers["Name"];
return filepath + "\r\n" + filename + "\r\n" + customHeader;
}
}
前端
前端 import 模块:jms-uploader
async function uploadToAliyun() {
//自定义请求头
var headers = function () {
return { "Custom-Header": "test" };
};
//提交的body
var dataBody = {
name: "abc"
};
var uploader = new JmsUploader("http://localhost:5200/Main/Test", [document.querySelector("#file1").files, document.querySelector("#file2").files], headers, dataBody);
uploader.setPartSize(1024*300);//设置分块大小300K
uploader.setUploadFilter("Aliyun");//设置服务器使用哪个upload filter
uploader.onUploading = function (percent, uploadedSize, totalSize) {
document.querySelector("#info").innerHTML = percent + "% " + uploadedSize + "," + totalSize;
};
try {
var ret = await uploader.upload();
alert(ret);
} catch (e) {
alert("错误:" + JSON.stringify(e));
}
}
html
<body>
<input id="file1" multiple type="file" />
<input id="file2" multiple type="file" />
<button onclick="uploadToAliyun()">
upload to aliyun oss
</button>
<div id="info"></div>
</body>
js上传多个文件到asp.net core,并实时转存到阿里云oss的更多相关文章
- js 上传txt格式文件
判断文件是否为.txt格式: $(".delbao .file").on("change",function(){ var acceptType = $(thi ...
- ASP.NET Core通过Nacos SDK读取阿里云ACM
背景 前段时间,cranelee 在Github上给老黄提了个issues, 问到了如何用Nacos的SDK访问阿里云ACM. https://github.com/catcherwong/nacos ...
- 宝塔安装Nextcloud,挂载在阿里云oss上,打造个人/企业高效私有云盘
如下未完整整理,看懂看不懂随缘.... 准备条件: 1.阿里云oss 2.阿里云ecs 3.环境:centos7.x 步骤: 1.centos中安装宝塔面板 2.下载NextCloud安装包,上传到宝 ...
- 如何把base64格式的图片上传到到阿里云oss c#版
今天碰到需要把canvas上的的图片转存到阿里云oss,于是百度了半天,一个能打的答案都没有.怒了,自己搞起. 代码超级简单,需要先引入nuget 中啊里云的oss api 1 byte[] arr ...
- C#结合js 上传文件和删除文件(技术点有:asp.net mvc ,nhibernate,ajax等)
之前做项目的时候要用到上传文件的功能,现在我总结一下,上传文件和删除文件的代码,在以后的使用的过程中也更方便查找. [HttpPost] public ActionResult EditUser() ...
- js上传整个文件夹
文件夹上传:从前端到后端 文件上传是 Web 开发肯定会碰到的问题,而文件夹上传则更加难缠.网上关于文件夹上传的资料多集中在前端,缺少对于后端的关注,然后讲某个后端框架文件上传的文章又不会涉及文件夹. ...
- ASP.NET Core WEB API 使用element-ui文件上传组件el-upload执行手动文件文件,并在文件上传后清空文件
前言: 从开始学习Vue到使用element-ui-admin已经有将近快两年的时间了,在之前的开发中使用element-ui上传组件el-upload都是直接使用文件选取后立即选择上传,今天刚好做了 ...
- ASP.NET CORE使用WebUploader对大文件分片上传,并通过ASP.NET CORE SignalR实时反馈后台处理进度给前端展示
本次,我们来实现一个单个大文件上传,并且把后台对上传文件的处理进度通过ASP.NET CORE SignalR反馈给前端展示,比如上传一个大的zip压缩包文件,后台进行解压缩,并且对压缩包中的文件进行 ...
- 使用ajaxfileupload.js上传文件
一直以来上传文件都是使用form表单上传文件,也看到过有人使用js上传文件,不过看起来蛮简单的也就没有怎么去理会.今天突然要使用这种方式上传文件,期间还遇到点问题.因此就记录下来,方便以后遇到这样的问 ...
- js 上传文件后缀名的判断 var flag=false;应用
js 上传文件后缀名的判断 var flag=false;应用 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional// ...
随机推荐
- 如何利用AI智能聊天机器人10秒钟做出一个故事绘本的神奇插件
原文链接:如何利用AI智能聊天机器人10秒钟做出一个故事绘本的神奇插件 ChatGPT以下称为AI智能聊天机器人 一.AI智能聊天机器人4中集成"Stories"插件 对于已经熟悉 ...
- MySQL数据库触发器讲解 [创建/删除/查询/select into]
刚学习实例完mysql触发器, 前来分享学习经验. 菜鸟装逼, 老鸟勿喷 先来认识一下有关触发器的一些关键词. 在使用触发器时, 这些关键词将被用到, 请记下它们的模样和用途(意思) cre ...
- 织梦DedeCMS文章内容页调用标签方法教程
织梦DedeCMS是新手站长使用比较多的建站软件,其模板制作也比较方便,一些站长朋友对其模板调用标签不是太熟悉,小编为大家介绍下织梦文章内容页调用标签的方法. 1.调用文章标题: {dede:fiel ...
- 「codeforces - 185D」Visit of the Great
link. 简单提一下做法,注意到 \(k^{2^a}\equiv k^{2^b}\equiv-1\equiv (-1)^{2^{b-a}}=1\pmod{(k^{2^a}+1,k^{2^{b}}+1 ...
- 【爬虫笔记】Python爬虫简单运用爬取代理IP
一.前言 近些年来,网络上的爬虫越来越多,很多网站都针对爬虫进行了限制,封禁了一些不规则的请求.为了实现正常的网络爬虫任务,爬虫常用代理IP来隐藏自己的真实IP,避免被服务器封禁.本文将介绍如何使用P ...
- Docker常见使用
DockerFile: FROM openjdk:8 MAINTAINER guotong ADD lpl-1.0-SNAPSHOT.jar lpl-1.0-SNAPSHOT.jar EXPOSE 8 ...
- BizSpring在线商城常见问题
一.什么是BizSpring在线商城? BizSpring在线商城是一个用java语言开发的完全开源的网络商城平台.该项目已经经历多次迭代升级是一个的成熟的在线商城解决方案,它具有轻量级,易于维护,操 ...
- Jmeter调用Python脚本,实现参数互相传递
首先传值到python 1:新增取样器--->os进程取样器 2:新建.bat文件 (写python脚本的路径和传参的个数:思路是:jmeter调用shell,用shell执行py) F:cd ...
- 轻松掌握组件启动之Redis集群扩展秘籍:轻松扩容与缩容,释放高性能潜能
扩展集群操作 扩容 在我们原始的集群基础上,我们决定增加一台主节点(8007)和一台从节点(8008),这样新增的节点将会在下图中以虚线框的形式显示在集群中. 1: 首先,在 /usr/local/r ...
- slice简介
简介 Go语言中的切片(slice)是一种灵活的数据结构,它构建在数组之上并提供了方便的方式来操作数组的一部分.切片的底层实现涉及到数组和一些元数据.以下是Golang切片的底层实现的详细介绍: 底层 ...