Нет заголовка "Access-Control-Allow-Origin" с возобновляемой загрузкой
Мы создаем возобновляемый URL-адрес для загрузки через облачный JSON API из нашего приложения App Engine, которое используется как на мобильных устройствах, так и в веб-приложении.
В веб-приложении, используя XmlHttpRequest для загрузки файла с возобновляемым URL-адресом, мы получаем следующую ошибку:
XMLHttpRequest не может загрузить https://www.googleapis.com/upload/storage/v1beta2/b/... Нет заголовка "Access-Control-Allow-Origin" на запрошенном ресурсе. Origin 'https://ourapp.appspot.com', следовательно, не допускается.
В инструментах разработчика Chrome в сетевом журнале отображается первый запрос OPTIONS с соответствующим заголовком запроса "Origin" и заголовком ответа "Access-Control-Allow-Origin", но следующий запрос PUT не работает, как упоминалось.
Корс xml на нашем ковше выглядит так:
<?xml version="1.0" encoding="UTF-8"?>
<CorsConfig>
<Cors>
<Origins>
<Origin>*</Origin>
</Origins>
<Methods>
<Method>PUT</Method>
<Method>GET</Method>
<Method>POST</Method>
<Method>HEAD</Method>
<Method>DELETE</Method>
<Method>OPTIONS</Method>
</Methods>
<ResponseHeaders>
<ResponseHeader>*</ResponseHeader>
</ResponseHeaders>
<MaxAgeSec>1800</MaxAgeSec>
</Cors>
</CorsConfig>
Любые предложения приветствуются.
Спасибо.
Ответы
Ответ 1
Разработал эту проблему и обнаружил, что это связано с отсутствием заголовка "origin" в исходном запросе POST, поступающем из App Engine.
Мой запрос POST содержит длину контента (устанавливается в 0), x-upload-content-type и origin, и все хорошо.
[1] https://cloud.google.com/storage/docs/json_api/v1/how-tos/upload#resumable
Ответ 2
Это известная проблема с использованием возобновляемой загрузки с помощью JSON API. Я предполагаю, что "источник" , используемый для запуска возобновляемой загрузки, и "источник" , используемый для загрузки данных, различен в вашем случае, правильно?
В этой проблеме участвуют две части:
1) При использовании возобновляемого протокола загрузки "начало" из первого запроса (загрузка) всегда используется для определения заголовка "access-control-allow-origin" в ответе, даже если вы используете другой "происхождение" для последующих запросов.
2) Конфигурация CORS в GCS работает только для XML API. Я думаю, что наша документация может использовать некоторые улучшения, чтобы сделать это более понятным, прямо сейчас это только упоминается здесь (https://developers.google.com/storage/docs/cross-origin#Sending-a-Cross-Domain_Request), если вы нажмете ссылку, чтобы увидеть, какие запросы URI будут реагировать на конфигурацию CORS. API JSON игнорирует конфигурацию CORS и всегда разрешает доступ к исходному коду в запросе на основе кросс-оригинала.
Итак, если вы используете возобновляемую загрузку с помощью JSON API, она будет использовать только "источник" из первого запроса и установить заголовок "access-control-allow-origin" в это начало. Таким образом, если происхождение изменяется в последующих запросах на загрузку, они не будут работать.
В настоящее время у вас есть два способа обойти эту проблему:
1) Используйте один и тот же источник для первого и последующих запросов.
2) Переключитесь на использование XML API и установите конфигурацию CORS в <Origin> * </Origin> .
Ответ 3
Проблема не в документе COR, показанном выше. Можно загрузить файлы с xhr, если запрос xhr является formdata, как описано здесь: http://www.html5rocks.com/en/tutorials/file/xhr2/#toc-sending. Если запрос не является FormData, мы получаем ошибку "Access-Control-Allow_Origin".
Это работает для меня:
$("input[type=file]").change(function() {
var formData = new FormData();
formData.append("field, ...);
formData.append("field, ...);
formData.append("file", filesList[0]);
var xhr = new XMLHttpRequest();
xhr.open('POST', "https://my-bucket.storage.googleapis.com/", true);
xhr.onload = function(e) {
console.log("File Uploaded!")
};
xhr.send(formData);
}
См. полный рабочий пример node.js: https://github.com/sfarthin/crop-rotate-and-sample-in-browser
Ответ 4
Конечная точка https://www.googleapis.com
не разрешает совместное использование ресурсов Cross-Origin (CORS). Это означает, что все браузеры будут препятствовать запросам при выпуске с веб-сайта, который не запущен на исходном хосте (www.googleapis.com).
Убедитесь, что вы сконфигурировали CORS для своего ковша, например:
<?xml version="1.0" encoding="UTF-8"?>
<CorsConfig>
<Cors>
<Origins>
<Origin>https://ourapp.appspot.com</Origin>
</Origins>
<Methods>
<Method>GET</Method>
<Method>HEAD</Method>
<Method>PUT</Method>
</Methods>
</Cors>
</CorsConfig>
Если он все еще не работает, установите <Origin>*</Origin>
, попробуйте свернуть и сообщить результат.