使用BlobStore的createUploadURL函數上傳到GCS(Google雲端存儲)時,我可以提供回調以及將發送到回調URL的標頭數據。在Google Cloud Storage簽署的URL中提供回調URL
似乎沒有成爲一個辦法做到這一點與GCS的signed URL's
我知道有Object Change Notification但將不允許用戶提供在後的頭上傳的具體信息,該方法它可能與createUploadURL的回調。
我的感覺是,如果createUploadURL可以做到這一點,就必須有辦法用簽名的URL來完成它,但我找不到任何文檔。我想知道是否有人可能知道createUploadURL如何實現回調調用行爲。
PS:我試圖搬開從createUploadURL因爲__BlobInfo__
實體它創造,這對於我的具體使用情況下,我並不需要的,並以某種方式似乎是不可磨滅的,並且浪費存儲空間。
更新:它的工作!這裏是如何:
長的答案來完成:
如果你看一下signed-URL頁,前面HTTP_Verb,在下描述,有一個微妙的說明,這個頁面只與GET,HEAD,PUT和DELETE有關,但是POST是一個完全不同的遊戲。我錯過了這一點,但事實證明這非常重要。
有一整頁HTTP Headers沒有列出可以與POST一起使用的重要頭文件;那頭是success_action_redirect,正如voscausa正確回答。
在POST頁谷歌「強烈建議」使用PUT,除非處理表單數據。但是,POST有一些PUT沒有的好功能。他們可能擔心POST會給我們提供太多的字符串來纏住自己。
但我想說這是完全值得的createUploadURL,並編寫自己的代碼重定向到回調。這裏是如何:
代碼:
如果您在Python voscausa的code正在努力是非常有幫助的。
我使用apejs在Java應用程序編寫的JavaScript,所以我的代碼如下所示:
var exp = new Date()
exp.setTime(exp.getTime() + 1000 * 60 * 100); //100 minutes
json['GoogleAccessId'] = String(appIdentity.getServiceAccountName())
json['key'] = keyGenerator()
json['bucket'] = bucket
json['Expires'] = exp.toISOString();
json['success_action_redirect'] = "https://" + request.getServerName() + "/test2/";
json['uri'] = 'https://' + bucket + '.storage.googleapis.com/';
var policy = {'expiration': json.Expires
, 'conditions': [
["starts-with", "$key", json.key],
{'Expires': json.Expires},
{'bucket': json.bucket},
{"success_action_redirect": json.success_action_redirect}
]
};
var plain = StringToBytes(JSON.stringify(policy))
json['policy'] = String(Base64.encodeBase64String(plain))
var result = appIdentity.signForApp(Base64.encodeBase64(plain, false));
json['signature'] = String(Base64.encodeBase64String(result.getSignature()))
上面的代碼首先提供相關的字段。 然後創建一個策略對象。然後它將對象串化並將其轉換爲一個字節數組(您可以在Java中使用.getBytes,我必須爲javascript編寫函數)。 編碼此數組的版本一個base64,填充政策字段。 然後它使用appidentity包進行簽名。最後簽名是base64編碼的,我們完成了。
在客戶端,json對象的所有成員都將被添加到窗體中,除了窗體的地址uri。
var formData = new FormData(document.forms.namedItem('upload'));
var blob = new Blob([thedata], {type: 'application/json'})
var keys = ['GoogleAccessId', 'key', 'bucket', 'Expires', 'success_action_redirect', 'policy', 'signature']
for(field in keys)
formData.append(keys[field], url[keys[field]])
formData.append('file', blob)
var rest = new XMLHttpRequest();
rest.open('POST', url.uri)
rest.onload = callback_function
rest.send(formData)
如果您沒有提供重定向,則成功的響應狀態將爲204。但是,如果你重定向,狀態將是200.如果你得到了403或400個關於簽名或策略的內容可能是錯誤的。看看responseText。如果通常有幫助。
有幾件事情需要注意:
- POST和PUT有一個簽名字段,但這些意味着略有不同的事情。在POST的情況下,這是政策的簽名。
- PUT有一個包含密鑰(對象名稱)的基地址,但用於POST的URL可能只包含存儲區名稱
- PUT要求從UNIX時期開始秒數過期,但POST要求它作爲ISO字符串。
- 認沽簽名應該URL編碼(Java語言:用URLEncoder.encode調用其包裝)。但對於POST,Base64編碼就足夠了。
- 通過擴展,POST對Base64.encodeBase64String(result.getSignature())進行擴展,並且不使用Base64.encodeBase64URLSafeString函數
- 您不能通過POST傳遞額外的頭文件;只允許在POST page中列出的那些。
- 如果您提供success_action_redirect一個URL,它會收到與鍵一個GET,鬥和ETAG。
- 使用POST的另一個好處是您可以提供大小限制。然而,使用PUT時,如果文件違反了您的大小限制,則只能在完全上傳後將其刪除,即使它是多個千兆字節。
有什麼不對createUploadURL?
以上方法是手動createUploadURL。 但是:
- 你沒有得到它創造了許多指標,是不可磨滅的那些
__BlobInfo__
對象。這讓我惱火,因爲它浪費了大量的空間(這讓我想起一個單獨的問題:issue 4231請去給它一個明星) - 您可以提供自己的對象的名稱,這有助於你的水桶創建文件夾。
- 您可以爲每個鏈接提供不同的到期日期。
對於非常非常少數的JavaScript應用程序,工程師:
function StringToBytes(sz) {
map = function(x) {return x.charCodeAt(0)}
return sz.split('').map(map)
}
還有一點讓我感到困惑的是,使用_createUploadUrl_時,可以在POST表單中提供自定義字段,但不能像POST api那樣提供自定義字段。 我試過使用python的_base64.urlsafe_b64decode_函數來查看是否可以從_createUploadUrl_的輸出中做出任何意義,但不幸的是輸出結果不是字符串。 – user2782503