Как описано здесь https://cloud.google.com/storage/docs/xml-api/post-object
Я могу использовать ${filename}
как часть ключа при загрузке файла в GCS из браузера (используя подписанный запрос).
Это здорово, потому что это та же самая переменная, которую использует S3.Но - проблема.На самом деле он не заменяет ${filename}
именем файла при загрузке.Это отлично работает на S3, но с GCS я буквально получаю $%7Bfilename%7D
в качестве ключа в ответе - очевидно, он не заменяет это на правильное значение.
Я строю запрос так:
export function uploadVideo(video) {
return new Promise((resolve, reject) => {
if (!video) {
resolve(null);
return;
}
// this fetches a presigned post object from the server:
request.get('/presigned_post')
.query({format: 'json'})
.end((err, response)=> {
if (!err && response.ok) {
request
.post(`https://${response.body.url.host}/`)
.field(response.body.fields)
.field('Content-Type', image.type)
.attach('file', image, image.name)
.end((err, response) => {
if (err) {
console.log("Error uploading image: ", err);
reject(err);
} else {
resolve({
location: response.text.match('<Location>' + '(.*?)' + '</Location>')[1],
bucket: response.text.match('<Bucket>' + '(.*?)' + '</Bucket>')[1],
key: response.text.match('<Key>' + '(.*?)' + '</Key>')[1],
checksum: response.text.match('<ETag>"' + '(.*?)' + '"</ETag>')[1]
});
}
});
}
});
});
}
Ключ some_folder/${filename}
, и он включен в данные формы для google (в response.fields
).
Вы видите, что я am , предоставляя имя файла с.attach('file', image, image.name)
.Это это загрузка корректно, только не заменяет ${filename}
var.
edit
Я сузил проблему больше.Мы запрашиваем S3 и GCS, чтобы получить поля в заданном посте.С S3, если я дам ключ ${filename}
, то получу именно то, что возвращается в полях:
def presigned_post(bucket_name:, key:, **opts)
response = s3_resource.
bucket(bucket_name).
presigned_post(key: key, content_type_starts_with: '', **opts)
{
fields: response.fields,
url: { host: URI.parse(response.url).host }
}
end
Поля здесь будут содержать "key"=>"${filename}"
.
Однако в случае GCSследующий код возвращает :key=>"$%7Bfilename%7D"
в полях:
# https://cloud.google.com/storage/docs/xml-api/post-object#usage_and_examples
# https://www.rubydoc.info/gems/google-cloud-storage/1.0.1/Google/Cloud/Storage/Bucket:post_object
def presigned_post(bucket_name:, key:, acl:, success_action_status:, expiration: nil)
expiration ||= (Time.now + 1.hour).iso8601
policy = {
expiration: expiration,
conditions: [
["starts-with", "$key", "" ],
["starts-with", "$Content-Type", "" ],
{ acl: acl },
{ success_action_status: success_action_status }
]
}
post_obj = get_bucket!(bucket_name).post_object(key, policy: policy)
url_obj = { host: URI.parse(post_obj.url).host }
# Have to manually merge in these fields
fields = post_obj.fields.merge(
acl: acl,
success_action_status: success_action_status
)
return { fields: fields, url: url_obj }
end
Если я вручную изменяю ключ в полях запроса GCS, тогда он работает.Это действительно то, что я должен делать?