阿里云OSS使用

文件迁移

迁移CentOS现有文件

1
2
wget http://gosspublic.alicdn.com/ossutil/1.6.10/ossutil64
chmod 755 ossutil64

生成配置文件

1
./ossutil64 config

比如 华北5 endpoint 就是

外网: oss-cn-huhehaote.aliyuncs.com

内网:oss-cn-huhehaote-internal.aliyuncs.com

上传命令

1
./ossutil64 cp -r /data/web_front/school_live_record_wgy/ oss://xhkjedu-wgy/

上传跳过重复文件

1
./ossutil64 cp -r -u /data/web_front/school_live_record_wgy/ oss://xhkjedu-wgy/

迁移Windows上的文件

下载并安装 ossbrowser。

支持平台 下载地址
Windows x32 Windows x32
Windows x64 Windows x64
Mac Mac
Linux x64 Linux x64

网页上传

引用和定义

上传跨域设置

https://help.aliyun.com/document_detail/32069.html?spm=a2c4g.11186623.2.25.45f13038rYUNwu#concept-32069-zh

下载

1
npm install ali-oss

引用

1
2
3
4
5
6
7
8
9
10
let OSS = require('ali-oss');

let ossclient = new OSS({
region: '<oss region>',
//云账号AccessKey有所有API访问权限,建议遵循阿里云安全最佳实践,创建并使用STS方式来进行API访问
accessKeyId: '<Your accessKeyId(STS)>',
accessKeySecret: '<Your accessKeySecret(STS)>',
stsToken: '<Your securityToken(STS)>',
bucket: '<Your bucket name>'
});

我用的是华北五

所以

region:oss-cn-huhehaote

其它的参看

STS临时授权访问OSS

上传

页面

1
<input type="file" @change="filechange($event, 0)"/>

事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
filechange(event, mindex) {
let userpicdom = event.target;
const data = userpicdom.files[0];
if (data) {
const index = data.name.lastIndexOf(".");
const suffix = data.name.substr(index + 1);
let filename = getfilename() + "." + suffix;
let filepath = this.$api.osspath + "userinfo/" + this.loginuser.userid +"/" + filename;
ossclient.put(filepath, data).then((res) => {
console.info(res);
if (res.url) {

}
});
}
},

我这里就先不用临时授权了 所以stsToken就不填

图片处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 填写源Object完整路径,例如exampledir/exampleobject.jpg。Object完整路径中不能包含Bucket名称。
const sourceImage = 'exampledir/exampleobject.jpg';
// 填写图片处理后的目标Object完整路径,例如exampledir/exampleobject-resize.jpg。Object完整路径中不能包含Bucket名称。
const targetImage = 'exampledir/exampleobject-resize.jpg';
async function processImage(processStr, targetBucket) {
const result = await ossclient.processObjectSave(
sourceImage,
targetImage,
processStr,
targetBucket
);
console.log(result.res.status);
}

// 将原图缩放为宽度1000px 高度自适应 并保存到原图所在Bucket。
processImage("image/auto-orient,1/resize,m_lfit,w_1000/quality,q_90", "examplebucket")

处理生成的字符串可以在下面的页面中生成,复制过来

https://oss.console.aliyun.com/bucket/oss-cn-huhehaote/xh-reports/process/img

先上传再压缩整体代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
async filechange(event, mindex) {
let userpicdom = event.target;
const data = userpicdom.files[0];
if (data) {
const index = data.name.lastIndexOf(".");
const suffix = data.name.substr(index + 1);
let filename = getfilename();
let filepath = `${this.$api.osspath}userinfo/${this.loginuser.userid}/${filename}.${suffix}`;
let filepath2 = `${this.$api.osspath}userinfo/${this.loginuser.userid}/${filename}_resize.${suffix}`;
console.info("filepath", filepath);
console.info("filepath2", filepath);
try {
let res = await ossclient.put(filepath, data);
if (res.url) {
console.info("原图的地址:" + res.url);
let processStr =
"image/auto-orient,1/resize,m_lfit,w_2000/quality,q_90";
let result2 = await ossclient.processObjectSave(
filepath,
filepath2,
processStr,
"xh-reports"
);
if (result2 && result2.status === 200) {
let url_new =
"https://psvmc.oss-cn-huhehaote.aliyuncs.com/" + filepath2;
console.info("处理后图片地址:", url_new);
}
}
} catch (e) {
this.$Message.warning("图片上传失败!");
}
}
},

页面导出Canvas跨域

服务器端对于跨域请求的处理流程如下:

  1. 首先查看http头部有无origin字段;
  2. 如果没有,或者不允许,直接当成普通请求处理,结束;
  3. 如果有并且是允许的,那么再看是否是preflight(method=OPTIONS);
  4. 如果不是preflight(简单请求),就返回Allow-Origin、Allow-Credentials等,并返回正常内容。
  5. 如果是preflight(预先请求),就返回Allow-Headers、Allow-Methods等,内容为空;

相关文章

通过img标签加载的图片,服务器并不会返回Access-Control-Allow-Origin:*,而浏览器就缓存了该url及其响应header,下次,就算想通过跨域的方式访问,而浏览器则不会再去问服务器,直接从缓存里面取,header告诉其不能跨域,这实际违背了服务器的意愿。也就是说,浏览器缓存了没有跨域信息的头。

这个问题在于你们没有输出 vary 的相应头,导致浏览器认为请求头里没有 origin 都是一样的缓存策略,如果用户先发了一个不带origin头的请求,再发一个带origin的请求,后者会默认从缓存内获取;

三种解决方案:

  1. OSS不管请求有没有origin头始终输出 access-control-allow 相关头;
  2. 始终输出vary:origin的头,告诉浏览器,对请求头是否包含origin的请求分别做缓存
  3. img标签图片添加crossorigin

方案一

可以在Nginx中配置响应头,这种方式的前提是我们用的自己的文件服务

方案二

未配置Vary之前,浏览器的缓存以url为唯一区分,配置Vary后,浏览器会以二者结合作为区分。

Vary其它取值情况看文档,不具体说明,聊聊可以解决问题的配置,Vary:Origin。

Origin是个有意思的header,仅在CORS请求与POST请求下才会携带该请求头,也就是说,我们直接通过img标签加载的请求并不会有Origin,而后通过xhr请求,同样的url,由于属于CORS请求,所以会带有Origin,浏览器会将其当成两种不同的资源。前面提到的另一种情况,从不同域名请求同一个资源也是同样的道理。

问题迎刃而解。

不过针对我们项目碰到的问题,要是使用阿里云OSS,因为阿里云后台仅支持配置9种可选的响应header,把Vary勾选上。

方案三

既然是第一次通过img加载图片造成的缓存“污染”,那么,我们让img加载图片的方式走CORS不就好了么?

1
<img src="xxxx" crossorigin />

但是如果我们的页面部分又加载的富文本,我们又不可能把所有的img标签都添加上crossorigin,那么这种方式显然不好 还得用上面的第二种方式。