在瀏覽器中使用AWS的SDK直接上傳文件到S3時,需要在S3 Bucket上配置CORS才能成功上傳,否則ajax請求會被瀏覽器攔截。
普通CORS訪問配置
官方文檔Cross-Origin Resource Sharing (CORS)中提供了開啓CORS的範例,摘錄如下:
<CORSConfiguration> <CORSRule> <AllowedOrigin>http://www.example1.com</AllowedOrigin> <AllowedMethod>PUT</AllowedMethod> <AllowedMethod>POST</AllowedMethod> <AllowedMethod>DELETE</AllowedMethod> <AllowedHeader>*</AllowedHeader> </CORSRule> <CORSRule> <AllowedOrigin>http://www.example2.com</AllowedOrigin> <AllowedMethod>PUT</AllowedMethod> <AllowedMethod>POST</AllowedMethod> <AllowedMethod>DELETE</AllowedMethod> <AllowedHeader>*</AllowedHeader> </CORSRule> <CORSRule> <AllowedOrigin>*</AllowedOrigin> <AllowedMethod>GET</AllowedMethod> </CORSRule> </CORSConfiguration>
支持Multipart Upload的配置
當上傳的文件比較大的時候,AWS的javascript的SDK會使用Multipart upload的方式來上傳, 而Multipart upload的機制中是需要用到Header中的Etag的,因此需要在S3的CORS的rule中配置允許暴露ETag, 也即需要添加<ExposeHeader>ETag</ExposeHeader>
示例Rule:
<?xml version="1.0" encoding="UTF-8"?> <CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> <CORSRule> <AllowedOrigin>http://localhost:3000</AllowedOrigin> <AllowedMethod>PUT</AllowedMethod> <AllowedMethod>POST</AllowedMethod> <ExposeHeader>ETag</ExposeHeader> <AllowedHeader>*</AllowedHeader> </CORSRule> </CORSConfiguration>
S3 Multipart Upload的原理在官方博客Amazon S3: Multipart Upload中有相關的說明。
如下是一個Parts Uploaded的PUT請求的response的示例。PUT成功上傳分片到S3後,S3返回的本次請求的Etag爲0a2f92d61cdc4682ba52adb9e077991f
分片全部上傳完畢後,SDK再調用POST請求,將之前分片的ETag和PartNumber組成完成的S3文件。
如下是最後CompleteMultipartUpload的POST請求的Payload, 可以看到0a2f92d61cdc4682ba52adb9e077991f
作爲請求的payload的一部分被髮送至S3。S3會根據payload將對應的partial block組成完整的S3文件。
如果不添加<ExposeHeader>ETag</ExposeHeader>
的話,Multipart upload的時候,AWS Javascript SDK會報Error: No access to ETag property on response. Check CORS configuration to expose ETag header.
的錯誤。
Reference
- Amazon S3: Multipart Upload
- Cross-Origin Resource Sharing (CORS)
- Amazon s3 Javascript- No ‘Access-Control-Allow-Origin’ header is present on the requested resource
轉自:https://www.jibing57.com/2018/12/11/how-to-enable-cors-on-S3/