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// ...
随机推荐
- svg动画 - 波浪动画
波浪 <path d="M 96.1271 806.2501 C 96.1271 806.2501 241.441 755.7685 384.5859 755.7685 C 529.8 ...
- UI自动化项目1说明 | 网页计算器自动化测试项目
需求: 1.对网页计算器, 进行加法的测试操作. 通过读取数据文件中的数据来执行用例. 2.网址: http://cal.apple886.com/ 测试点: 1.加法:1+1=2 2+9!=10 . ...
- 《Python魔法大冒险》009 魔法之语:字符串的奥秘
随着小鱼和魔法师的深入,他们来到了一个被薄雾笼罩的湖泊.湖中央有一个小岛,岛上有一棵巨大的古树,树上挂满了闪闪发光的果实,每一个果实上都刻着一个字母或符号. 小鱼好奇地问:"这些是什么果实? ...
- JS深入学习笔记 - 第三章.变量作用域与内存
1.原始值和引用值 ECMScript变量包含两种不同类型是数据:原始值和引用值. 原始值:最简单的数据.有6中原始值:Undefined.Null.Boolean.Number.String和Sym ...
- 33家国内外知名的手机广告平台的SDK名单汇总,吐血推荐
下面格式:第一行是广告平台名称,第二行是SDK的包名特征,第三行是平台网站 多盟cn.domob.androidhttp://www.domob.cn/百度推广SDK com.baidu统计SDK c ...
- 几个易错的python小知识点
大家好,我是暴走の海鸽~ 本期整理了几个基础python防坑小常识,希望对大家有所帮助. 1. type == object? 执行以下代码的结果是什么: >>> isinstanc ...
- Unity - UIWidgets 7. Redux接入(二) 把Redux划分为不同数据模块
参考QF.UIWidgets 参考Unity官方示例 - ConnectAppCN 前面说过,当时没想明白一个问题,在reducer中每次返回一个new State(), 会造成极大浪费,没想到用什么 ...
- 天上掉 Pizza
实在不知道错哪了... 对着 std 检查了好几遍了QAQ 题解见注释(不过估计题解也是错的,不然为什么写错啊QAQ #include<bits/stdc++.h> using names ...
- nginx、rabbitmq、redis、zookeeper、zkui安装脚本
nginx安装脚本 #!/bin/bash yum install -y wget pcre-devel openssl openssl-devel gcc ###安装perl### cd /usr/ ...
- InfiniBand 的前世今生
今年,以 ChatGPT 为代表的 AI 大模型强势崛起,而 ChatGPT 所使用的网络,正是 InfiniBand,这也让 InfiniBand 大火了起来.那么,到底什么是 InfiniBand ...