背景
项目里有图片上传的需求,具体实现是后端生成presigned url(预签名url,里面包含上传到AWS S3所需要的一些认证标识信息)给到前端,前端通过这个URL将文件上传到云服务上。但是上传成功后,从CDN上下载下来的文件打不开,而且只有前端有这个问题,客户端可以正常上传,一开始以为是框架问题,而且亚马逊官方也没有直接上传相关的文档(都是使用SDK的方式上传),所以问题很难定位,后来在github上找到了方案。
相关步骤
-
从后端获取presigned url ,亚马逊官网有Java、PHP、node等生成presigned url的文档在这里插入图片描述
-
使用presigned url上传图片,前端使用的是element UI + axios, 这里使用的element UI 自定义上传的方式,特别需要注意的就是直接上传文件,不要用formdata的格式上传
HTML部分
<el-upload
class="avatar-uploader"
action="123"
:http-request="upload"
:before-upload="beforeAvatarUpload">
<img v-if="params.defaultImgUrl" :src="params.defaultImgUrl" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
upload(res)
let file = res.file; //注意:直接上传file文件,不要用FormData对象的形式传
let config = {
headers: {
'Content-Type': 'multipart/form-data'
//从接口获取presigned url
getUploadUrl({uploadType: 6}).then(res => {
let result = res.data;
if (result.code === 0) {
const info = JSON.parse(result.msg);
//需要用put方法上传,post会报405,aws官方规定是put方法
axios.put(info.presignedUrl, file, config)
.then(res => {
if (res.status == 200) {
this.params.defaultImgUrl = info.cdnUrl;
}).catch(
err => {
console.log(err)
}).catch(err => {
console.log('get upload info', err)
一般图片、文件上传都是使用FormData对象传递二进制文件,所以笔者一开始也是采用的这种方式上传到AWS上,但是上传完之后,下载后的图片无法打开,将其二进制数据与原文件二级制数进行对比,发现有额外的二进制数据
- 后来在github上找到了解决方案,原来使FormData对象上传文件到aws上会损坏原文件的二进制数据,直接上传文件对象就行
附上参考的解决方案github地址:
https://github.com/aws/aws-sdk-js/issues/547
背景项目里有图片上传的需求,具体实现是后端生成presigned url(预签名url,里面包含上传到AWS S3所需要的一些认证标识信息)给到前端,前端通过这个URL将文件上传到云服务上。但是上传成功后,从CDN上下载下来的文件打不开,而且只有前端有这个问题,客户端可以正常上传,一开始以为是框架问题,而且亚马逊官方也没有直接上传相关的文档(都是使用SDK的方式上传),所以问题很难定位,后来在github上找到了方案。相关步骤从后端获取presigned url ,亚马逊官网有Java、PH..
aws-s3-signurl
AWS CLI当前不具有对URL进行签名的功能,以限制时间访问安全存储桶。 这个简单的实用程序采用存储桶名称和(可选)键名称,并为其输出签名的URL。 如果仅提供了存储桶名称,则将为每个密钥输出一个已签名的URL。 如果还指定了键,则仅输出该存储桶/键组合。
凭证是从环境变量或~/.aws/config (如果存在)中加载的。 有关更多详细信息,请参阅。
npm install --global aws-s3-signurl
aws-s3-signurl {bucketname} [{keyname}] [{expires}]
如果仅提供了存储桶名称,则将列出存储桶的内容。
如果提供了密钥,则仅输出该密钥。
如果提供了到期时间(数字,以秒为单位),则该链接将在该秒内有效(默认值= 900秒)。
MinIO 是在 GNU Affero 通用公共许可证 v3.0 下发布的高性能对象存储。它是与 Amazon S3 云存储服务兼容的 API。使用 MinIO 为机器学习、分析和应用程序数据工作负载构建高性能基础架构。
搭建mini
MinIO 需要一个持久卷来存储配置和应用程序数据。但是,出于测试目的,您可以通过简单地传递一个目录(/data在下面的示例中)来启动 MinIO 。该目录是在容器启动时在容器文件系统中创建的。但是容器退出后所有的数据都丢失了。如果打算持久化,进行挂载即可。
docke
使用presigned URLs,你可以让浏览器直接上传一个文件到S3服务,而不需要暴露S3服务的认证信息给这个用户。下面就是使用minio-js实现的一个示例程序。
服务端代码
const MinIO = require('minio')
var client = new MinIO.Client({
endPoint: 'play.min.io',
port: 9000,
useSSL: true,
accessKey: 'Q3A
response.setContentType("text/html;charset=utf-8");
这里将text写成了test之后,不知道返回的流是什么类型,所以变成了下载。
当我们通过java的API上传文件的时候就会发现,我们把java的API封装了一下,提供了一个接口给其他应用调用,那么整个的上传流程就变成了“应用客户端”-->“JavaAPI端”-->“minio服务端”。中间通过JavaAPI转了一次。比如我们的“应用客户端”是web浏览器的时候,能不能直接从浏览器上传到“minio服务端”呢?答案是可以的,minio有提供JSSDK,我们可以通过JSAPI直接上传到“minio服务端”。
JSSDK
参考官网的文档:https://docs.min.i
* aws s3 获取s3预上传文件presigned url
* @param [type] $key [aws的目录]
* @return [type] [string]
public static fu
AWS S3(Amazon Simple Storage Service)是亚马逊提供的一种高度可扩展的对象存储服务。S3允许用户以云存储方式存储和检索任意数量的数据。以下是关于AWS S3的一些重要特性:
1. 可扩展性:AWS S3提供了高度可扩展的存储解决方案,能够适应任意规模的需求。无论是存储几个G的个人文件还是处理TB级别的数据,S3都能够满足需求。
2. 安全性:AWS S3提供多层次的安全控制来保护数据的完整性和安全性。用户可以通过控制访问权限来限制对存储桶和对象的访问。此外,S3还提供了加密功能,可以对数据进行加密,确保数据在传输和存储过程中的安全。
3. 可靠性:AWS S3采用了多副本存储和自动修复机制,确保数据的可用性和持久性。S3将数据存储在多个设备和多个区域,并且自动处理设备故障,以确保数据不会丢失。
4. 数据访问:通过AWS S3,用户可以轻松地在任何地方访问其存储的数据。S3提供了REST和SOAP接口,可以通过编程方式进行高效、低延迟的数据访问。此外,S3还提供了网页界面,方便用户直接通过浏览器进行数据管理和操作。
5. 成本效益:AWS S3采用按需计费模式,根据用户实际存储的数据量和数据传输的流量进行计费。用户只需支付实际使用的存储空间和传输流量,无需提前购买硬件设备或维护硬件设备,从而节约了成本。
总之,AWS S3是一种可靠、安全、高度可扩展的云存储解决方案。通过提供灵活的数据管理和访问方式,以及强大的安全控制和可靠性,S3帮助用户轻松地存储和管理各种类型的数据,并实现数据的安全性和可用性。