AWS S3使用预签名URL上传文件

最近使用AWS S3进行预签名URL上传文件开发,预签名URL上传好处是文件不需要经过后端中转,直接前端上传文件到公有云AWS的对象存储。前端同事遇到了点问题,上传不成功。我看了下主要集中在2个方向,一是自己定义了form数据,然后后端是没有定义相关meta-data的,导致上传的整个form被当做了文件内容数据。二是后端签名URL生成的时候content-type的定义和前端定义的不一致。以下是后端和前端的代码:

AWS预签名生成示例代码,使用software.amazon.awssdk s3依赖:

public String getUploadURL(String objectName) {
        URL url = s3Presigner.presignPutObject(x ->
                x.signatureDuration(Duration.ofMinutes(10))
                        .putObjectRequest(y ->
                                y.bucket(ossProperties.getBucketName())
                                        .key(objectName)
                                        .build()).build()).url();
        return url.toString();
    }

AWS上传文件前端代码示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>AWS S3 JS Integration</title>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script type="application/javascript">
        function upload() {
            fetch('http://127.0.0.1:8080/api/upload/url', {
                method: 'GET',
                headers: {'Accept': 'application/json'}
            }).then(resp => resp.json())
                .then(data => {
                    //创建文件流
                    const fileInput = document.querySelector('#fetchFile');
                    const fileStream = fileInput.files[0];
					//响应的预签名URL放在了response的data属性里,所以是resp.data.uploadUrl,下同
                    console.log(data.data);
                    // 发送请求
                    fetch(data.data.uploadUrl, {
                        method: 'PUT',
                        body: fileStream
                    })
                        .then(response => response.json())
                        .then(data => console.log(data))
                        .catch(error => console.log('Error:', error))
                })
        }

        function uploadAxios() {
            axios.get('http://127.0.0.1:8080/api/upload/url')
                .then(function (response) {
                    const data = response.data;
                    console.log(data.data);
                    //创建文件流
                    const fileInput = document.querySelector('#axiosFile');
                    const fileStream = fileInput.files[0];
                    axios({
                        method: "put",
                        url: data.data.uploadUrl,
						//重点,直接将原始二进制流赋给data
                        data: fileStream, 
                        headers: {
                            //必须设置成流
                            "Content-Type": "application/octet-stream",
                        },
                        //必须设置
                        responseType: "blob",
                    })
                        .then(function (response) {
                            console.log(response);
                        })
                        .catch(function (error) {
                            console.log(error);
                        })
                })
                .catch(function (error) {
                    //请求失败处理
                    console.log(error);
                });

        }
		
		function uploadAxios2() {
            axios.get('http://127.0.0.1:8080/api/upload/url')
                .then(function (response) {
                    const data = response.data;
                    console.log(data.data);
                    //创建文件流
                    const fileInput = document.querySelector('#axiosFile');
                    const fileStream = fileInput.files[0];
                    //转换形式
                    const reader = new FileReader();
                    reader.readAsArrayBuffer(fileStream);
                    //上传图片
                    reader.onload = () => {
                        //上传图片接口  data.data.uploadUrl:上传图片地址  修改请求头
                        axios.put(data.data.uploadUrl, reader.result, {header: {"Content-Type": "multipart/form-data"}})
                            .then(res => {
                                console.log(res)
                            }).catch(err => {
                            console.log(err)
                        })
                    };
                })
                .catch(function (error) {
                    //请求失败处理
                    console.log(error);
                });

        }
    </script>
</head>
<body>
<p>fetch上传</p><input id="fetchFile" type="file" onchange="upload()" placeholder="fetch上传">
<br/>
<br/>
<br/>
<p>axios上传</p><input id="axiosFile" type="file" onchange="uploadAxios()" placeholder="axios上传">
</body>
</html>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值