带有签名URL的PUT
请求的响应不包含标头Access-Control-Allow-Origin
。
import os
from datetime import timedelta
import requests
from google.cloud import storage
os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = <path to google credentials>
client = storage.Client()
bucket = client.get_bucket('my_bucket')
policies = [
{
'origin': ['*'],
'method': ['PUT'],
}
]
bucket.cors = policies
bucket.update()
blob = bucket.blob('new_file')
url = blob.generate_signed_url(timedelta(days=30), method='PUT')
response = requests.put(url, data='some data')
for header in response.headers.keys():
print(header)
输出:
X-GUploader-UploadID
ETag
x-goog-generation
x-goog-metageneration
x-goog-hash
x-goog-stored-content-length
x-goog-stored-content-encoding
Vary
Content-Length
Date
Server
Content-Type
Alt-Svc
如您所见,没有CORS标头。因此,我可以得出结论,GCS不正确/完全不支持CORS吗?
答案 0 :(得分:1)
跨源资源共享(CORS)允许来自不同源的资源之间进行交互。 默认情况下,为了防止恶意行为,Google Cloud Storage中默认将其禁止/禁用。
请记住以下规则,使用Cloud Libraries,Rest API或Cloud SDK启用它:
使用用户/服务帐户进行身份验证,并具有Cloud Storage类型的权限:FULL_CONTROL
。
Using XML API要获取正确的CORS标头,请使用以下两个URL之一:
- storage.googleapis.com/[BUCKET_NAME]
- [BUCKET_NAME].storage.googleapis.com
来源storage.cloud.google.com/[BUCKET_NAME]
将不使用CORS标头进行响应。
headers = {
'ORIGIN': '*'
}
response = requests.put(url, data='some data', headers=headers)
for header in response.headers.keys():
print(header)
给出以下输出:
X-GUploader-UploadID
ETag
x-goog-generation
x-goog-metageneration
x-goog-hash
x-goog-stored-content-length
x-goog-stored-content-encoding
Access-Control-Allow-Origin
Access-Control-Expose-Headers
Content-Length
Date
Server
Content-Type
答案 1 :(得分:0)
我遇到了这个问题。对我来说,问题是我使用的是POST
而不是PUT
。此外,我必须设置上载的Content-Type
以匹配用于生成表单的内容类型。演示中的默认Content-Type是“ application / octet-stream”,因此我必须将其更改为上载的内容类型。在执行XMLHttpRequest时,我只需要直接发送文件即可,而不必使用FormData。
这就是我获得签名网址的方式。
const options = {
version: 'v4',
action: 'write',
expires: Date.now() + 15 * 60 * 1000, // 15 minutes
contentType: 'application/octet-stream',
};
// Get a v4 signed URL for uploading file
const [url] = await storage
.bucket("lsa-storage")
.file(upload.id)
.getSignedUrl(options as any);