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// ...
随机推荐
- 谈一谈电商API接口
随着电商行业的快速发展,越来越多的企业开始意识到并利用API接口来提升其电商平台的功能和效率.但是,对于普通用户来说,对API接口可能还不太了解.那么,什么是API接口,特别是电商API接口呢?本文将 ...
- Git命令详细使用指南
Git命令详细使用指南 Git是一种广泛使用的版本控制系统,它可以帮助开发人员跟踪变更.协作项目和有效管理代码仓库.无论你是初学者还是有经验的用户,理解各种Git命令对于高效的代码管理至关重要. 安装 ...
- Java读取某个文件夹下的所有文件(支持多级文件夹)
源码如下: package com.vocy.water.batch; import java.io.FileNotFoundException; import java.io.IOException ...
- 4399 Flash游戏专用浏览器, 无需安装Flash插件
目前所有的主流浏览器都已经不再支持Flash了,即使有一些国内浏览器还支持flash,但只能安装国内特供版Flash Player. 但问题的关键在于,这个国内特供版跟 Adobe 海外发行的版本是两 ...
- 使用JAVA调用KRPANO加密XML
KRPano自带的命令行工具krpanotools可以加密XML,具体的参数说明如下语法: krpanotools32.exe encrypt [OPTIONS] inputfiles input ...
- 聊聊数据库事务内嵌TCP连接
最近再看项目代码,发现很多的service里面,喜欢在事务内部再去调用HTTP请求,简单分析下此种方式的利弊与解决策略. 概述 在数据库内部嵌套TCP连接(一般是HTTP调用或是RPC远程调用). @ ...
- To_Heart—题解——好多好多!
1.CF1860D link && submission 发现自己并不会处理纯纯的 dp 甚至自己根本不会dp! 定义 dp_{i,j,k} 状态表示前 i 个字符有 j 个 0, 0 ...
- std::copy与std::back_inserter引发的惨案
#include <iostream> #include <vector> #include <numeric> #include <sstream> ...
- 形象描绘TCP三次握手和四次挥手
一.TCP三次握手TCP 三次握手就好比两个人在街上隔着50米看见了对方,但是因为雾霾等原因不能100%确认,所以要通过招手的方式相互确定对方是否认识自己.形象描绘TCP三次握手和四次挥手 张三首先向 ...
- Hugging Face 分词器新增聊天模板属性
一个幽灵,格式不正确的幽灵,在聊天模型中游荡! 太长不看版 现存的聊天模型使用的训练数据格式各各不同,我们需要用这些格式将对话转换为单个字符串并传给分词器.如果我们在微调或推理时使用的格式与模型训练时 ...