#node.js #angular #google-cloud-platform #cors #google-cloud-storage
# #node.js #angular #google-облачная платформа #cors #google-облачное хранилище
Вопрос:
Я разрабатываю приложение Angular для отображения содержимого хранилища Google Cloud Storage. Для обратной стороны я использую облачные функции Google в NodeJS
Как упоминалось в документации для загрузки файла, я создал функцию для генерации подписанного URL-адреса, но когда я отправляю свой файл с подписанным URL-адресом, я получаю ошибку cors в браузере
Я тестировал с postman, он загружает пустой файл
Вот моя лямбда-функция:
// Imports the Google Cloud client library
const {Storage} = require('@google-cloud/storage');
// Creates a client
const storage = new Storage();
exports.generateSignedUrl = (req, res) => {
// generate signed url to use for file upload
const filename = req.query.fileName;
console.log('filename ', filename);
const filetype = req.query.fileType;
console.log('filetype ', filetype);
const bucketName = 'nx-terega-omega';
res.set('Access-Control-Allow-Origin', "*");
res.set('Access-Control-Allow-Headers', "Origin, X-Requested-With,
Content-Type, Accept, Authorization");
if (req.query.fileName !== null amp;amp; req.query.fileName !== undefined
amp;amp; req.query.fileType !== null amp;amp; req.query.fileType !== undefined)
{
generateV4UploadSignedUrl(bucketName, filename).then(function (value)
{
console.log('File Url response ', value);
res.status(200).send(JSON.stringify({'url': value}));
}).catch(error => {
res.status(404).send('Error while generating signed url');
});
} else {
res.status(500).send('Filename not found');
}
};
async function generateV4UploadSignedUrl(bucketName, filename, filetype) {
// [START storage_generate_upload_signed_url_v4]
// These options will allow temporary uploading of the file with outgoing
// Content-Type: application/octet-stream header.
const options = {
version: 'v4',
action: 'write',
expires: Date.now() 15 * 60 * 1000, // 15 minutes
contentType: filetype,
};
// Get a v4 signed URL for uploading file
const [url] = await storage
.bucket(bucketName)
.file(filename)
.getSignedUrl(options);
console.log('Generated PUT signed URL:');
console.log(url);
console.log('You can use this URL with any user agent, for example:');
console.log("curl -X PUT -H 'Content-Type: application/octet-stream' " `--upload-file my-file '${url}'`);
return url;
// [END storage_generate_upload_signed_url_v4]
}
Когда я получаю подписанный URL-адрес, я отправляю ему свой файл внутри, но он возвращается
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Ответ №1:
Как упоминалось в ответе Брэндона Ярбро, мне пришлось настроить cors в Google Cloud. Мне чего-то не хватало в моей конфигурации
[
{
"origin": ["http://example.appspot.com"],
"responseHeader": ["*"],
"method": ["GET", "HEAD", "DELETE", "PUT"],
"maxAgeSeconds": 3600
}
]
Вы должны включить PUT
в method
и вставить *
responseHeader
, потому Content-Type
что этого недостаточно
Ответ №2:
Подписанные URL-адреса используют XML API GCS. Этот API допускает запросы из разных источников, но не включает его по умолчанию. Вам нужно будет указать политику CORS для вашей корзины.
Например, вы можете создать политику CORS, подобную следующей (допустим, это файл с именем policy.json
):
[
{
"origin": ["http://example.appspot.com"],
"responseHeader": ["Content-Type"],
"method": ["GET", "HEAD", "DELETE"],
"maxAgeSeconds": 3600
}
]
Полное описание документа политики CORS находится здесь: https://cloud.google.com/storage/docs/xml-api/put-bucket-cors#request_body_elements
Теперь давайте применим эту политику к корзине:
gsutil cors set policy.json gs://my-bucket-name
В документации есть дополнительные инструкции по включению CORS в корзине: https://cloud.google.com/storage/docs/configuring-cors
Комментарии:
1. Он не работает и возвращает
has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
2. Включает ли ваша политика CORS метод OPTIONS? Вероятно, это необходимо для прохождения предполетного запроса.
3. Я нашел решение, это была
responseHeader
проблема