Vue中实现图片上传,上传后的图片回显,存储图片到服务器 【使用对象存储OSS】

本文涉及的产品
对象存储 OSS,20GB 3个月
对象存储OSS,敏感数据保护2.0 200GB 1年
对象存储 OSS,恶意文件检测 1000次 1年
简介: 这篇文章介绍了在Vue中实现图片上传到阿里云OSS对象存储服务的完整流程,包括服务端签名直传的前提知识、后端设置、前端组件封装以及图片上传和回显的效果展示。

文章目录

  • 1 前提知识
    • 1.1 服务端签名后直传
      • 1.1.1 流程和源码解析
      • 1.1.2 实现步骤
    • 1.2 Aliyun Spring Boot OSS 示例(接入微服务)
      • 1.2.1 简略说明
      • 1.2.2步骤
  • 2、项目中实际应用
    • 2.1 后端设置
    • 2.2 前端设置
    • 2.3 实现的效果

三连哦

前言
以下只提供一种思路,对新手可能不太友好。

这里将前端Vue上传的图片直接存储到服务器上,
Alibaba Cloud OSS: 阿里云对象存储服务(Object Storage Service,简称 OSS),是阿里云提供的海量、安全、低成本、高可靠的云存储服务。您可以在任何应用、任何时间、任何地点存储和访问任意类型的数据。

1 前提知识

1.1 服务端签名后直传

官网地址文档:服务端签名后直传

介绍如何基于Post Policy的使用规则在服务端通过各种语言代码完成签名,然后通过表单直传数据到OSS。由于服务端签名直传无需将AccessKey暴露在前端页面,相比JavaScript客户端签名直传具有更高的安全性

1.1.1 流程和源码解析

在这里插入图片描述

1.1.2 实现步骤

  • 1.用户向应用服务器请求上传Policy和回调。
    将客户端源码中的upload.js文件的以下代码片段的变量serverUrl的值设置为应用服务器的URL。
// serverUrl是用户获取签名和Policy等信息的应用服务器的URL,请将下面的IP和Port配置为您自己的真实信息。
serverUrl = 'http://88.88.XX.XX:8888'

设置完成后,客户端会向该serverUrl发送Get请求来获取需要的信息

本场景为服务端签名后直传,不涉及上传回调。因此,您需要注释客户端源码中的upload.js文件内的’callback’ : callbackbody字段,以关闭上传回调功能。

{
  'key' : key + '${filename}',
  'policy': policyBase64,
  'OSSAccessKeyId': accessid,
   // 设置服务端返回200状态码,默认返回204。
  'success_action_status' : '200', 
  'callback' : callbackbody,
  'signature': signature,
}
    1. 应用服务器返回上传Policy和签名给用户。应用服务器侧的签名直传服务会处理客户端发送的Get请求消息,您可以设置对应的代码让应用服务器能够给客户端返回正确的消息。以下是签名直传服务返回给客户端消息Body内容的示例:


- 3.用户使用Post方法向OSS发送文件上传请求`

> 说明
除file表单域外,包含key在内的其他所有表单域的大小均不能超过8 KB。
客户端上传默认同名覆盖,如果您不希望覆盖同名文件,可以在上传请求的header中携带参数x-oss-forbid-overwrite,并指定其值为true。当您上传的文件在OSS中存在同名文件时,该文件会上传失败,并返回FileAlreadyExists错误。

```java
new_multipart_params = {
     // key表示上传到Bucket内的Object的完整路径,例如exampledir/exampleobject.txtObject,完整路径中不能包含Bucket名称。
     // filename表示待上传的本地文件名称。
     'key' : key + '${filename}',
     'policy': policyBase64,
     'OSSAccessKeyId': accessid,
     // 设置服务端返回状态码为200,不设置则默认返回状态码204。
     'success_action_status' : '200',    
     'signature': signature,
 };

1.2 Aliyun Spring Boot OSS 示例(接入微服务)

1.2.1 简略说明

项目说明:

如果您的应用是 Spring Cloud 应用,且需要使用阿里云的 OSS 服务进行云端的文件存储,例如电商业务中常见的商品图片存储,那么您可以使用 OSS starter 完成 Spring Cloud 应用的对象存储。

1.2.2步骤

简略步骤,更加详细说明请自行查看官网说明

1 修改 pom.xml 文件,引入 aliyun-oss-spring-boot-starter。

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>aliyun-oss-spring-boot-starter</artifactId>
</dependency>
  • 2、在配置文件中配置 OSS 服务对应的 accessKey、secretKey 和 endpoint。
// application.properties
alibaba.cloud.access-key=your-ak
alibaba.cloud.secret-key=your-sk
alibaba.cloud.oss.endpoint=***
  • 3、注入 OSSClient 并进行文件上传下载等操作。
 @Service
 public class YourService {
     @Autowired
     private OSSClient ossClient;

     public void saveFile() {
         // download file to local
         ossClient.getObject(new GetObjectRequest(bucketName, objectName), new File("pathOfYourLocalFile"));
     }
 }

2、项目中实际应用

2.1 后端设置

在父工程下,新创建一个服务专门用来处理其它第三方的服务。

pom文件中配置

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alicloud-oss</artifactId>
        </dependency>

application.yml配置文件修改

同时需要将服务注册到nacos中

spring:
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
    alicloud:
      access-key: +++
      secret-key: +++
      oss:
        endpoint: +++
        bucket: ++++

  application:
    name: 名称

server:
  port: 90000

nacos配置动态修改

spring.application.name=+++
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
spring.cloud.nacos.config.namespace=++++

spring.cloud.nacos.config.ext-config[0].data-id=oss.yml
spring.cloud.nacos.config.ext-config[0].group=DEFAULT_GROUP
spring.cloud.nacos.config.ext-config[0].refresh=true

编写一个接口,用来实现服务器将上传Policy和签名返回给用户


@RestController
public class OssController {

    @Autowired
    OSS ossClient;

    @Value("${spring.cloud.alicloud.oss.endpoint}")
    private String endpoint;
    @Value("${spring.cloud.alicloud.oss.bucket}")
    private String bucket;

    @Value("${spring.cloud.alicloud.access-key}")
    private String accessId;

    @RequestMapping("/oss/policy")
    public R policy() {

        String host = "https://" + bucket + "." + endpoint; // host的格式为 bucketname.endpoint
        String format = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        String dir = format + "/"; // 用户上传文件时指定的前缀。

        Map<String, String> respMap = null;
        try {
            long expireTime = 30;
            long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
            Date expiration = new Date(expireEndTime);
            PolicyConditions policyConds = new PolicyConditions();
            policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
            policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);

            String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
            byte[] binaryData = postPolicy.getBytes("utf-8");
            String encodedPolicy = BinaryUtil.toBase64String(binaryData);
            String postSignature = ossClient.calculatePostSignature(postPolicy);

            respMap = new LinkedHashMap<String, String>();
            respMap.put("accessid", accessId);
            respMap.put("policy", encodedPolicy);
            respMap.put("signature", postSignature);
            respMap.put("dir", dir);
            respMap.put("host", host);
            respMap.put("expire", String.valueOf(expireEndTime / 1000));

        } catch (Exception e) {
            System.out.println(e.getMessage());
        }

        return R.ok().put("data",respMap);
    }
}

2.2 前端设置

上传封装为一个组件

<template> 
  <div>
    <el-upload
      action="服务器要存储的地址"
      :data="dataObj"
      list-type="picture"
      :multiple="false" :show-file-list="showFileList"
      :file-list="fileList"
      :before-upload="beforeUpload"
      :on-remove="handleRemove"
      :on-success="handleUploadSuccess"
      :on-preview="handlePreview">
      <el-button size="small" type="primary">点击上传</el-button>
      <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过10MB</div>
    </el-upload>
    <el-dialog :visible.sync="dialogVisible">
      <img width="100%" :src="fileList[0].url" alt="">
    </el-dialog>
  </div>
</template>
<script>
   import {policy} from './policy'
   import { getUUID } from '@/utils'

  export default {
    name: 'singleUpload',
    props: {
      value: String
    },
    computed: {
      imageUrl() {
        return this.value;
      },
      imageName() {
        if (this.value != null && this.value !== '') {
          return this.value.substr(this.value.lastIndexOf("/") + 1);
        } else {
          return null;
        }
      },
      fileList() {
        return [{
          name: this.imageName,
          url: this.imageUrl
        }]
      },
      showFileList: {
        get: function () {
          return this.value !== null && this.value !== ''&& this.value!==undefined;
        },
        set: function (newValue) {
        }
      }
    },
    data() {
      return {
        dataObj: {
          policy: '',
          signature: '',
          key: '',
          ossaccessKeyId: '',
          dir: '',
          host: '',
          // callback:'',
        },
        dialogVisible: false
      };
    },
    methods: {
      emitInput(val) {
        this.$emit('input', val)
      },
      handleRemove(file, fileList) {
        this.emitInput('');
      },
      handlePreview(file) {
        this.dialogVisible = true;
      },
      beforeUpload(file) {
        let _self = this;
        return new Promise((resolve, reject) => {
          policy().then(response => {
            console.log("响应的数据",response)
            resolve(true)
          }).catch(err => {
            reject(false)
          })
        })
      },
      handleUploadSuccess(res, file) {
        console.log("上传成功...")
        this.showFileList = true;
        this.fileList.pop();
        this.fileList.push({name: file.name, url: this.dataObj.host + '/' + this.dataObj.key.replace("${filename}",file.name) });
        this.emitInput(this.fileList[0].url);
      }
    }
  }
</script>
<style>

</style>

上传成功后的图片回显

      <el-table-column
        prop="logo"
        header-align="center"
        align="center"
        label="品牌logo地址"
      >
        <template slot-scope="scope">
          <img :src="scope.row.logo" style="width: 100px; height: 80px" />
        </template>
      </el-table-column>

2.3 实现的效果

图片上传

在这里插入图片描述

添加成功后,图片展示
在这里插入图片描述

服务器上的的图片
在这里插入图片描述
在这里插入图片描述

相关实践学习
借助OSS搭建在线教育视频课程分享网站
本教程介绍如何基于云服务器ECS和对象存储OSS,搭建一个在线教育视频课程分享网站。
相关文章
|
24天前
|
存储 人工智能 Kubernetes
AI 场景深度优化!K8s 集群 OSSFS 2.0 存储卷全面升级,高效访问 OSS 数据
阿里云对象存储OSS是一款海量、安全、低成本、高可靠的云存储服务,是用户在云上存储的高性价比选择…
|
2月前
|
存储 Kubernetes 对象存储
StrmVol存储卷:如何解锁K8s对象存储海量小文件访问性能新高度?
如何提升海量文件的数据读取速率,对于AI训练集管理、量化回测、时序日志分析等场景尤为重要。阿里云容器服务(ACK))支持StrmVol类型存储卷,基于底层虚拟块设备及内核态文件系统,显著降低海量小文件访问延迟。
|
26天前
|
存储 数据挖掘
服务器数据恢复—EMC存储raid5阵列数据恢复案例
服务器存储数据恢复环境: EMC某型号存储中有一组由8块硬盘组建的raid5磁盘阵列。 服务器存储故障: raid5阵列中有2块硬盘离线,存储不可用,上层应用崩了。
|
1月前
|
存储 运维 数据挖掘
服务器数据恢复—EqualLogic存储硬盘出现坏道的数据恢复案例
一台EqualLogic某型号存储中有一组由16块SAS硬盘组建的RAID5阵列。上层采用VMFS文件系统,存放虚拟机文件,上层一共分了4个卷。 磁盘故障导致存储不可用,且设备已经过保。
|
2月前
|
存储 Kubernetes 对象存储
StrmVol 存储卷:解锁 K8s 对象存储海量小文件访问性能新高度
本文介绍了阿里云容器服务(ACK)支持的StrmVol存储卷方案,旨在解决Kubernetes环境中海量小文件访问性能瓶颈问题。通过虚拟块设备与内核态文件系统(如EROFS)结合,StrmVol显著降低了小文件访问延迟,适用于AI训练集加载、时序日志分析等场景。其核心优化包括内存预取加速、减少I/O等待、内核态直接读取避免用户态切换开销,以及轻量索引快速初始化。示例中展示了基于Argo Workflows的工作流任务,模拟分布式图像数据集加载,测试结果显示平均处理时间为21秒。StrmVol适合只读场景且OSS端数据无需频繁更新的情况,详细使用方法可参考官方文档。
540 144
|
29天前
|
存储 人工智能 测试技术
AI 场景深度优化!K8s 集群 OSSFS 2.0 存储卷全面升级,高效访问 OSS 数据
OSSFS 2.0通过轻量化协议设计、协程化技术及FUSE3低级API重构,实现大文件顺序读写与小文件高并发加载的显著提升,在实际测试中表现出高达数十倍的吞吐量增长。适用于机器学习训练、推理等对高带宽低延迟要求严苛的场景,同时支持静态和动态挂载方式,方便用户在ACK集群中部署使用。
239 34
|
2月前
|
存储 弹性计算 数据管理
阿里云对象存储oss怎么收费?存储费用+流量收费标准
阿里云对象存储OSS收费标准包含存储费、流量费及请求费等,支持按量付费与包年包月两种模式。标准型本地冗余存储按量付费价格为0.09元/GB/月,包年包月500GB预留空间优惠价118元/年。流量费仅收取公网出方向费用,忙时0.50元/GB,闲时0.25元/GB。更多详情可参考官方页面。
|
1月前
|
存储 安全 Linux
Dell OpenManage Enterprise 4.4 - Dell 服务器、存储和网络设备集中管理软件
Dell OpenManage Enterprise 4.4 - Dell 服务器、存储和网络设备集中管理软件
58 4
Dell OpenManage Enterprise 4.4 - Dell 服务器、存储和网络设备集中管理软件
|
1月前
|
存储 消息中间件 弹性计算
阿里云服务器ECS计算型c7和通用算力型u1在适用场景、计算性能、网络与存储性能等方面的对比
阿里云ECS服务器u1和c7实例在适用场景、性能、处理器特性等方面存在显著差异。u1为通用算力型,性价比高,适合中小企业及对性能要求不高的场景;c7为企业级计算型,采用最新Intel处理器,性能稳定且强大,适用于高性能计算需求。u1支持多种CPU内存配比,但性能一致性可能受底层平台影响;c7固定调度模式,确保高性能与稳定性。选择时可根据预算与性能需求决定。
115 23
|
3月前
|
存储 弹性计算 安全
阿里云服务器付费类型、地域、镜像、存储、带宽和安全组设置与选择注意事项参考
在我们通过自定义购买的方式购买阿里云服务器器ECS时,会有多个选项,有的新手用户可能并不是很清楚这些选项是什么,选择或设置时需要注意什么,本文将从付费类型、地域与可用区、镜像、存储、带宽和安全组等多个方面,为您详细解析云服务器购买过程中各个参数与配置的选择注意事项,以供参考。
313 66

热门文章

最新文章