目前我尝试了两种方案,第一种没调试通,可能我方式不对,求大佬看看问题出现在哪
1、 使用签名URL进行临时授权
根据官网操作 授权访问 (aliyun.com)
大致流程是
1. 前端先安装阿里云oss的browser.js,可通过npm或者cdn直接引入。
2. 获取临时授权访问oss凭证。
3.客户端使用sts构造签名请求 代码来自官网
// 向您搭建的STS服务获取临时访问凭证。
fetch('http://your_sts_server/')
.then(resp => resp.json())
.then(result => {
const store = new OSS({
// 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
accessKeyId: result.AccessKeyId,
accessKeySecret: result.AccessKeySecret,
// 从STS服务获取的安全令牌(SecurityToken)。
stsToken: result.SecurityToken,
// 填写Bucket所在地域。以华东1(杭州)为例,设置region为oss-cn-hangzhou。
region: 'oss-cn-hangzhou',
// 填写Bucket名称,例如examplebucket。
bucket: 'examplebucket'
});
// 生成签名URL。
// 填写Object完整路径,例如ossdemo.txt。Object完整路径中不能包含Bucket名称。
const url = store.signatureUrl('ossdemo.txt');
console.log(url);
})
4. 使用签名URL进行临时授权 代码来自官网
// 以下代码用于生成对象签名URL。
const url = store.signatureUrl('exampleobject.txt');
console.log(url);
// 获取上传exampleobject.txt文件的签名URL。
const url = store.signatureUrl('exampleobject.txt', {
// 设置过期时间为3600秒。
expires: 3600,
// 设置请求方式为PUT。默认请求方式为GET。
method: 'PUT'
});
console.log(url);
const url = store.signatureUrl('exampleobject.txt', {
expires: 3600,
method: 'PUT',
// 设置Content-Type。
'Content-Type': 'text/plain; charset=UTF-8',
});
console.log(url);
// 获取下载exampleobject.txt文件的签名URL,使用浏览器访问时默认直接预览要下载的文件。
const url = store.signatureUrl('exampleobject.txt', {
expires: 3600,
response: {
'content-type': 'text/custom',
// 获取下载exampleobject.txt文件的签名URL,配置文件HTTP头中的Content-Disposition为attachment,实现浏览器访问时自动下载文件,并自定义下载后的文件名称。
// 如果您希望直接在浏览器中预览文件,配置文件HTTP头中的Content-Disposition为inline并使用Bucket绑定的自定义域名进行访问。
'content-disposition': 'attachment'
}
});
console.log(url);
// 生成带有图片处理参数的签名URL
// 获取图片文件exampleobject.png签名URL。
// 填写不包含Bucket名称在内的Object完整路径。
const url = store.signatureUrl('exampleobject.png', {
// 设置图片处理参数。
process: 'image/resize,w_200'
});
console.log(url);
// 设置过期时间为3600秒。
const url = store.signatureUrl('exampleobject.png', {
expires: 3600,
process: 'image/resize,w_200'
});
console.log(url);
5. 使用签名url上传文件 代码来自官网
// signatureUrl填写生成的签名URL。
const url = 'signatureUrl';
var xhr = new XMLHttpRequest();
xhr.open('PUT', url, true);
xhr.onload = function () {
// 请求结束后,在此处编写处理代码。
};
xhr.send(null);
// xhr.send('string');
// xhr.send(new Blob());
// xhr.send(new Int8Array());
// xhr.send({ form: 'data' });
// xhr.send(document);
问题就来了,在跟后端商量好以后,觉得在前端写AccessKey ID,bucket等不安全,会暴露。所以3和4部在后端进行完成,前端操作如下:
1. 像后端发送请求,请求内容为图片类型(.jpg / .png这些) 后端返回生成的签名url
url地址为: oss服务器地址 + / xxx.jpg (xxx为后台随机生成文件名)
2. 我拿到签名url以后,直接给这个url地址发送put请求,携带请求头: 'x-oss-storage-class' : 'Standard' 和 file文件
结果并不能通,报403错误 访问被拒绝。求大佬解决一下错误的原因
2、 服务端签名后直传 (成功的方案)
参考链接: vue+element-ui+阿里云oss服务端签名后直传图片的示例 - 简书 (jianshu.com)
参考链接: 前后端分离。前端实现参数签名,后端实现接口验签_Anliexo的博客-优快云博客_前后端验签
官方文档: 服务端签名后直传 (aliyun.com)
后台直接参考官网
前端: vant3中Uploader 文件上传处理方式
1. Uploader 文件调用after-read文件读取完成后的回调函数 并且ResultType为file
<van-uploader v-model="fileList" multiple :after-read="afterRead" result-type="file"/>
2. 在after-read函数内 还是向后台发送请求,拿到accessid、dir、expire、host、name、policy、signature
accessid | 用户请求的AccessKey ID。 |
host | 用户发送上传请求的域名。 |
policy | 用户表单上传的策略(Policy),Policy为经过Base64编码过的字符串。详情请参见Post Policy。 |
signature | 对Policy签名后的字符串。详情请参见Post Signature。 |
expire | 由服务器端指定的Policy过期时间,格式为Unix时间戳(自UTC时间1970年01月01号开始的秒数)。 |
dir | 限制上传的文件前缀。 |
3. 构造formData格式, 并且把上述参数添加进来
const formData = new FormData();
formData.append("key", imgToken.name)
formData.append("success_action_status", 200)
formData.append("OSSAccessKeyId", imgToken.accessid)
formData.append("policy", imgToken.policy)
formData.append("signature", imgToken.signature)
注意: accessid 官网写的是accessid, 实际上要传 OSSAccessKeyId (贼坑)
success_action_status 不传200 如果上传成功会返回204
key必传! key为 oss路径地址 /xxxx.jpg 不包含oss服务器地址
4. 把files文件也添加进来
formData.append('file', files.file)
5. 发送post请求, url为oss文件服务器地址 ,data为formData