Google Storage API - Resumable Upload, AJAX, CORS Error



收到一个奇怪的错误。

当用户想要上传文件时,他们会向我的服务器发送 AJAX 请求。我的服务器使用 OAuth2 向 Google 的服务器验证服务器端,创建访问令牌,开始断点续传,并将断点续传上传 URI 和访问令牌传递给浏览器。

然后,浏览器直接上传到谷歌存储。

一切似乎都很好。该文件进入存储桶没有问题,但我仍然在 Chrome 上收到 CORS 错误,我不确定在哪里或为什么。这是我的javascript代码的简化版本:

var file = document.getElementById("fileInput").files[0];
var request = requestUpload();
var token = request.token;
var uri = request.uri;
var r = new XMLHttpRequest();
r.open('PUT', uri, true);
r.setRequestHeader("Authorization", "Bearer "+token);
r.send(file);`

很简单 - 但我仍然遇到这个常见错误:

XMLHttpRequest cannot load https://www.googleapis.com/upload/storage/v1/b/*****. No 'Access-Control-Allow-Origin' header is present on the requested resource.

尽管它似乎完全起作用。Javascript 是否请求查看某些默认不允许我查看的内容?我不想有错误。

XMLHttpRequest 对象还会在完成所有上载后触发错误事件。我猜这个请求期待谷歌的某种反馈,但它没有得到,JavaScript正在成为JavaScript的拉丁语,所以我发现的大部分讨论都是关于jQuery的。

非常感谢!

我刚刚遇到了这个确切的问题。 让我挠了挠头,但我想出了一个解决方案。 它的文档很少,并且行为并不完全有意义,但是如果您查看此页面上的最后一个项目符号点

https://cloud.google.com/storage/docs/cross-origin

使用可恢复上传协议时,来自第一个(开始上传(请求的源始终用于确定响应中的访问控制-允许-源标头,即使您对后续请求使用不同的源也是如此。因此,您应该对第一个和后续请求使用相同的源,或者如果第一个请求与后续请求具有不同的源,请使用 CORS 配置设置为 * 的 XML API。

所以我所做的是在来自服务器的可恢复会话启动请求中添加了Origin: http://example.com请求标头。 这样,与该上传会话 ID 对应的所有客户端请求都将根据该源进行检查。

我仍然觉得奇怪的一件事是浏览器发出的OPTIONS预检请求(至少对我来说(允许任何内容通过,即使PUT请求失败。

即使在执行gsutil cors get gs://your-bucket时使用此配置,您也需要根据@Craig的答案启动初始 POST 请求:

[{"maxAgeSeconds": 3600, "method": ["GET", "PUT", "POST", "HEAD", "DELETE"], "origin": ["*"], "responseHeader": ["*"]}] .

例如使用 golang 很容易将Origin传递给 gcloud 请求。有了r http.Request输入,您可以执行r.Header.Get("Origin")并将其传递给在gcloud上调用POST的函数。这是我在 golang 中编写的一个函数:

func GetUploadURL(bucket, object, contentType, origin string, expires time.Time) (string, error) {
    url, err := storage.SignedURL(bucket, object, &storage.SignedURLOptions{
        GoogleAccessID: "your-service-account@your-gcloud-project.iam.gserviceaccount.com",
        PrivateKey:     pkey, // set this in package init() function
        Method:         http.MethodPost,
        Expires:        expires,
        ContentType:    contentType,
        Headers:        []string{"x-goog-resumable:start"},
    })
    if err != nil {
        return "", err
    }
    req, err := http.NewRequest("POST", url, nil)
    if err != nil {
        return "", err
    }
    req.Header.Set("Content-Type", contentType)
    req.Header.Set("x-goog-resumable", "start")
    req.Header.Set("Origin", origin)
    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        return "", err
    }
    defer resp.Body.Close()
    return resp.Header.Get("Location"), nil
}

相关内容

  • 没有找到相关文章

最新更新