ASP.NET Web API + VUE3 整合阿里云OSS,后端API生成预签名上传Url,前端VUE进行上传

1、后端API

我用的是.net sdk6,所以先安装了这个Aliyun.OSS.SDK.NetCore

下面是后端生成上传Url的参考代码,主意request.ContentType,如果这里要是设置了,那么前端也要设置成一样的,如果前端是获取文件的contentType,可以传到后端来使用,我这里就没有进行设置,我目前只传图片。

objectKey是你要上传到的bucket下面的文件夹和你要指定的文件名。

主要是不想把这些key secret暴露在前端,这几个参数首先要保证正确。

复制代码
private const string AccessKeyId = "你的";
private const string AccessKeySecret = "你的";
private const string Endpoint = "http://oss-cn-beijing.aliyuncs.com"; //改成你的
private const string BucketName = "你的";

/// <summary>
/// 获取临时上传路径
/// </summary>
/// <returns></returns>
[Route("get-oss-url"), HttpPost]
[Authorize]
public IActionResult GetUserList([FromBody] FileUploadModel model)
{
    OutResult outResult = new OutResult();

    var client = new OssClient(Endpoint, AccessKeyId, AccessKeySecret);

    // 设置 URL 的有效期(例如 10 分钟)
    var expiration = DateTime.Now.AddMinutes(15);

    var objectKey = $"{model.folder}/{ Guid.NewGuid().ToString()+".jpg" }";


    GeneratePresignedUriRequest request = new GeneratePresignedUriRequest(BucketName, objectKey, SignHttpMethod.Put);
    request.Expiration = expiration;
    //request.ContentType = "image/jpeg";

    var signedUrl = client.GeneratePresignedUri(request);

    // 生成签名 URL
    //var signedUrl = client.GeneratePresignedUri(BucketName, objectKey, expiration, SignHttpMethod.Put);

    outResult.data = signedUrl.ToString();

    return Ok(outResult);
}

2、前端VUE

主要是几点,

1、调用后端生成预签名的上传url的接口,得到预先签名上传url。

2、Content-Type的设置。

复制代码
async function beforeUpload(file) {
  // 检查文件类型和大小
  var isImage = file.type.startsWith("image/");
  var isLt2M = file.size / 1024 / 1024 < 2;

  if (!isImage) {
    this.$message.error("只能上传图片文件");
  }
  if (!isLt2M) {
    this.$message.error("图片大小不能超过 2MB");
  }

    //这里调用后端生成上传url的接口,赋值给了uploadAction
  await getOssUploadUrl({
    folder: "goods"
  })
    .then(res => {
      uploadAction.value = res.data;
      console.log(uploadAction.value);
    })
    .catch(error => {
      message("获取上传路径失败", { type: "error" });
    });

  return isImage && isLt2M;
}
// 这里使用axios进行上传,如果后端使用的是put方法,这里也要用put方法
function handleUpload(options) {
  const { file } = options;
  try {
    // 使用 axios 或其他方式上传文件
    //const formData = new FormData();
    //formData.append("file", file);
    console.log(uploadAction.value);
    const response = axios.put(uploadAction.value, file, {
      headers: {
        "Content-Type": "" //image/jpeg
      }
    });

    // 上传成功,调用 onSuccess 回调
    options.onSuccess(response);
  } catch (error) {
    console.error("上传失败", error);
    options.onError();
  }
}

function handleSuccess(response, file, fileList) {
  console.log("文件上传成功", response);
}
const handleRemove: UploadProps["onRemove"] = (uploadFile, uploadFiles) => {
  console.log(uploadFile, uploadFiles);
};

const handlePictureCardPreview: UploadProps["onPreview"] = uploadFile => {
  dialogImageUrl.value = uploadFile.url!;
  dialogVisible.value = true;
};


<el-form-item label="商品图片" label-width="100">
          <el-upload
            v-model:file-list="fileList"
            :http-request="handleUpload"
            list-type="picture-card"
            :before-upload="beforeUpload"
            :on-success="handleSuccess"
            :on-preview="handlePictureCardPreview"
            :on-remove="handleRemove"
          >
            <el-icon><Plus /></el-icon>
          </el-upload>

          <el-dialog v-model="dialogVisible">
            <img w-full :src="dialogImageUrl" alt="Preview Image" />
          </el-dialog>
        </el-form-item>

3、阿里云oss的跨域设置

4、遇到的问题

1、遇到的第一个问题就是http://oss-cn-beijing.aliyuncs.com,这个地址用http还是https,这个和你前端最好一致,另外如果用https需要在oss配置证书,我嫌麻烦,直接使用了http。

2、从https改成http,就遇到了跨域的问题,然后就配置跨域。

3、跨域配置完,就遇到了上传403,说签名错误的问题,原来前端是new FormData();上传,后来改成直接传file,后端获取签名的时候也不指定ContentType,就好了。

4、图片可以上传了之后,发现在浏览器里面访问图片的时候不是预览而是下载,而vue里面访问直接就是403,我把防盗链的白名单加上了,因为是本地的测试,加的是localhost,图片在vue内可以显示了,在浏览器里还是下载,这个就先不管了。

相关推荐
慧一居士3 分钟前
Vite项目中使用Less步骤,详细使用示例
前端·css
花间相见23 分钟前
【LangChain组件03】—— LangChain Agents 执行与状态:工作流程与状态管理实战
java·前端·langchain
kyriewen38 分钟前
面试官让我用 AI 重构一个 8 年陈的 React 组件——他说他不看代码,只看我会不会拆
前端·javascript·面试
计算机魔术师39 分钟前
700吉瓦「幽灵用电」:美国AI数据中心的抢电闹剧正在失控
前端
IT_陈寒1 小时前
JavaScript数组排序踩的坑,差点让我加班到凌晨
前端·人工智能·后端
风骏时光牛马1 小时前
提示词工程:大模型交互的核心构建艺术
前端
今日无bug2 小时前
大模型的回答是怎么一个字一个字蹦出来的?前端流式输出解析
前端·llm·agent
计算机魔术师2 小时前
Anthropic 复盘 Claude 模型越权访问真实系统事件并改进对齐与安全措施
前端
掘金者阿豪2 小时前
Seedance 2.0/2.5 虚拟素材能跨 Key 共用吗?一次讲清 Asset ID、账号隔离与 SaaS 素材架构
前端·后端