前端·
前期准备
- 进入阿里云OSS存储-Bucket列表,创建bucket
- 进入RAM控制台,添加访问权限
- 创建用户 注:OpenAPI访问打钩
- 下载CSV文件,获取AccessKeyId、AccessKeySecret
服务端签名
- 根据步骤创建
配置跨域规则
创建项目
- 以
express
为例,创建任意文件夹打开终端,执行以下步骤
// 初始化 package.json
npm init
// 下载相关包
npm install express moment ali-oss -s
- 创建
server.js
文件,运行node server.js
,启动node服务http://127.0.0.1:3000/signature
。文件内容如下:
// server.js
const express = require('express');
const app = express();
const moment = require("moment");
const OSS = require("ali-oss");
const hostname = "127.0.0.1";
const port = 3000;
app.listen(port, function () {
console.log(`http://${hostname}:${port}`)
})
// 应用服务器核心代码解析
// 可以不用回调callback
app.get("/signature", async (req, res) => {
const config = {
// 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
accessKeyId: "LTAI5tMdm5QTzsGZoTtLw1p4",
accessKeySecret: "0uMZ4TNfAnvexZGJETIKReINP20Fiq",
// 填写Bucket名称。
bucket: "lg-blog-test",
// 设置上传回调URL,即回调服务器地址,用于处理应用服务器与OSS之间的通信。OSS会在文件上传完成后,把文件上传信息通过此回调URL发送给应用服务器。例如callbackUrl填写为https://oss-demo.aliyuncs.com:23450。
// callbackUrl: 'yourCallBackUrl',
// 当您需要设置上传到OSS文件的前缀时,请配置此项,否则置空即可。
// 此处采用时间划分
dir: "blog/" + moment(new Date()).format("YYYYMMDD") + "/",
};
const client = new OSS(config);
const date = new Date();
date.setDate(date.getDate() + 1);
const policy = {
expiration: date.toISOString(), //设置Unix时间戳(自UTC时间1970年01月01号开始的秒数),用于标识该请求的超时时间。
conditions: [
["content-length-range", 0, 1048576000], //设置上传文件的大小限制。
],
};
// 设置跨域资源共享规则CORS。
res.set({
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "PUT,POST,GET",
});
// 调用SDK获取签名。
const formData = await client.calculatePostSignature(policy);
// 填写Bucket外网域名。
const host = 'https://lg-blog-test.oss-cn-hangzhou.aliyuncs.com';
// 上传回调。
// const callback = {
// callbackUrl: config.callbackUrl, // 设置回调请求的服务器地址,例如http://oss-demo.aliyuncs.com:23450。
// // 设置回调的内容,例如文件ETag、资源类型mimeType等。
// callbackBody:
// "filename=${object}&size=${size}&mimeType=${mimeType}&height=${imageInfo.height}&width=${imageInfo.width}",
// callbackBodyType: "application/x-www-form-urlencoded", // 设置回调的内容类型。
// };
// 返回参数。
const params = {
expire: moment().add(1, "days").unix().toString(),
policy: formData.policy, // 从OSS服务器获取到的Policy。
signature: formData.Signature, // 从OSS服务器获取到的Signature。
accessKeyId: formData.OSSAccessKeyId, // 从OSS服务器获取到的OSS AccessKeyId。
host, // 格式为https://bucketname.endpoint,例如https://bucket-name.oss-cn-hangzhou.aliyuncs.com。
// callback: Buffer.from(JSON.stringify(callback)).toString("base64"), // 通过Buffer.from对JSON进行Base64编码。
dir: config.dir, // 获取到的文件前缀。
};
res.json(params);
});
启动后,如下:
客户端调用
- 创建
index.html
,并运行。文件内容如下:
// index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>OSS web直传</title>
</head>
<body>
<input id="file" type="file" name="" id="" >
<img id="img" width='max-content' height = 'max-content' src="" alt="">
</body>
<script>
const fileDom = document.getElementById('file')
const imgDom = document.getElementById('img')
fileDom.onchange = async (e) => {
const file = e.target.files[0]
// 获取签名信息
const data = await fetch('http://localhost:3000/signature')
const signatureInfo = await data.json()
// web直传
const formData = new FormData()
const name = signatureInfo.dir + file.name
formData.append('key', signatureInfo.dir + file.name)
formData.append('policy', signatureInfo.policy)
formData.append('OSSAccessKeyId', signatureInfo.accessKeyId)
formData.append('success_action_status', '200') // 默认值
formData.append('signature', signatureInfo.signature)
formData.append('file', file)
formData.append('x-oss-object-acl', 'public-read') // 只读访问权限
const response = await fetch(signatureInfo.host, {
method: 'POST',
body: formData
})
if (response.ok) {
const url = `${signatureInfo.host}/${name}`
imgDom.setAttribute('src', url)
}
}
</script>
</html>
此处采用 vscode 插件运行:
阿里云服务器查看,上传成功。如下:
遇到的问题
- 报错信息:You have no right to access this object because of bucket acl.
解决:读写权限设置为公共读
,保存后即可访问。
如下: