簡體   English   中英

為什么 Google Cloud Storage 總是回答 cors 錯誤:請求的資源上不存在“Access-Control-Allow-Origin”header

[英]Why is Google Cloud Storage always answering with cors error: No 'Access-Control-Allow-Origin' header is present on the requested resource

我正在嘗試從客戶端瀏覽器將文件上傳到 Google Cloud Storage (GCS)。 為此,我在 node.js 中有一個后端從 GCS 請求簽名 URL,然后將其傳輸到前端客戶端以上傳文件。 Signed URL請求碼如下:

const options = {
    version: "v4",
    action: "write",
    expires: Date.now() + 15 * 60 * 1000, // 15 minutes
    contentType: content_type,
  };

  // Get a v4 signed URL for uploading file
  const [url] = await storage
    .bucket(bucketName)
    .file(filename)
    .getSignedUrl(options)

這是工作。 當我嘗試在客戶端上使用 Signed URL 時,問題就出現了。 每個請求都以以下錯誤結束:

在'https://storage.googleapis.com/deplo.nets_models/keras_logo.png?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=urlsigner%40deplo.nets.iam.gserviceaccount.com 訪問XMLHttpRequest %2F20200711%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20200711T192805Z&X-Goog-Expires=900&X-Goog-SignedHeaders=content-type%3Bhost&X-Goog-Signature=82b73435e4759e577e9d3b8056c7c69167fdaac5f0f450381ac616034b4830a7661bdb0951a82bf749a35dc1cf9a8493b761f8993127d53948551d7b33f552d118666dcf8f67f494cfaabf2268d7235e955e1243ce3cd453dcc32552677168ad94c6f1fca0032eb57941a806cc14139915e3cd3efc3585497715a8ad32a1ea0278f2e1165272951ae0733d5c6f77cc427fd7ff69431f74f1f3f0e7779c28c2437d323e13a2c6474283b264ab6dc6a94830b2b26fde8160684839a0c6ea551ca7eff8e2d348e09a8c213a93c0532f6fed1dd167cd9cf3480415c0c35987b27abd03684e088682eb5e89008d33dcbf630b58ea6b86e7d7f6574466aa2daa982566' from origin 'http://localhost:3000' has been被 CORS 策略阻止:沒有 'Access-Control-Allow-Origin' header 出現在請求的資源。

我已經使用以下 JSON 在 GCS 存儲桶上設置了 CORS 策略:

[
  {
    "origin": ["*"],
    "method": ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
    "responseHeader": ["*"],
    "maxAgeSeconds": 120
  }
]

(例如,我也嘗試將來源具體列為 http://localhost:3000)

應該提到的是,我已經讓它在一種特定情況下工作:當上傳有效負載只是一個普通字符串時。 由於某種原因,它工作正常。

我已經在網上查找了所有可能的類似錯誤,但到目前為止無濟於事。 任何的想法?

更新:終於讓它工作了! 我必須添加contentType: 'application/octet-stream',processData: false,才能正常工作。 否則我收到錯誤:

  1. CORS 錯誤Access to fetch at 'https://storage.googleapis.com/...' from origin 'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled. Access to fetch at 'https://storage.googleapis.com/...' from origin 'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
  2. Uncaught TypeError: Illegal invocationUncaught (in promise) TypeError: Failed to execute 'arrayBuffer' on 'Blob': Illegal invocation

所以最終的 AJAX 請求看起來像這樣(工作):

$.ajax({
  url: <GCS signed upload URL>,
  type: 'PUT',
  data: f, //file object
  contentType: 'application/octet-stream', //seems to be required
  processData: false, //seems to be required
})

我還必須使用以下命令設置存儲桶 CORS:

gsutil cors set gcs_cors.json gs://<my_bucket>

文件gcs_cors.json內容為:

[
  {
    "origin": ["https://<myapp>.appspot.com", http://localhost:8080"],
    "responseHeader": ["Content-Type"],
    "method": ["GET", "HEAD", "DELETE", "PUT", "POST"],
    "maxAgeSeconds": 120
  }
]

原帖:我不確定這對你有什么作用(雖然很高興,)。 我曾嘗試直接使用該文件並使用表單數據,但它不起作用。 上傳到 GCS 似乎是一個非常令人沮喪的過程。 我希望文檔有一個完整的工作示例(前端/后端),但似乎並非如此。

我發現出了什么問題。 在上傳代碼(瀏覽器端)中,我傳遞了一個FormData object 作為要上傳的數據,由於某種原因觸發了上面的 CORS 錯誤。 當我直接傳遞文件時,我修復了它。

因此,不要使用以下內容:

var data = new FormData()
data.append('file', event.target.files[0])

我直接使用event.target.files[0]中的文件。

我遇到了完全相同的問題,我傳遞的選項有問題,請嘗試將選項更改為

const options = {
    action: "write",
    expires: Date.now() + 15 * 60 * 1000, // 15 minutes
  }

這個解決方案對我有用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM