API контактов Google из браузера заблокирован политикой CORS
У меня возникли проблемы с отправкой запроса в API контактов Google из моего браузера в среде разработки.
Я пытаюсь запросить фид контактов из моего веб-приложения, размещенного по адресу https://localhost:3001/, отправив запрос XHR на https://www.google.com/m8/feeds/contacts/default/thin?alt=json&access_token=MYTOKEN&max-results=5000&v=3.0
Ранее мы использовали JSONP для выполнения этого запроса (как предлагалось на различных других справочных форумах), но недавно эта ошибка начиналась с этой ошибки:
Refused to execute script from 'https://www.google.com/m8/feeds/contacts/default/thin?alt=json&access_token=MYTOKEN&max-results=5000&v=3.0&callback=jQuery33107099178438653957_1542737952472&_=1542737952473' because its MIME type ('application/json') is not executable, and strict MIME type checking is enabled.
Я понимаю, что теперь это не удается, потому что браузер проверяет MIME-тип ответа и потому что это не application/javascript
, он не должен оцениваться как скрипт и, следовательно, JSONP не работает. Мы пытались попросить application/javascript
но кажется, что API не даст нам ответ с этим mimetype.
Сейчас мы пытаемся навести порядок, но сталкиваемся с проблемой CORS, которая, как мне кажется, является причиной того, что весь Интернет в первую очередь говорит друг другу использовать JSONP.
Когда мы пытаемся сделать запрос без JSONP, мы получаем эту ошибку
Access to XMLHttpRequest at 'https://www.google.com/m8/feeds/contacts/default/thin?alt=json&access_token=MYTOKEN&max-results=5000&v=3.0' from origin 'https://localhost:3001' 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.
Однако в глубине форума поддержки Google кто-то предложил использовать googleapis.com
вместо google.com
, Как жаворонок, мы попробовали это, и это действительно работает. Моя проблема сейчас в том, что я понятия не имею, почему это работает или будет продолжать работать. В документах не упоминается использование этого нового хоста - они упоминают googleapis.com
URL-адрес как область OAuth только для чтения, но это кажется касательным к этой проблеме. Является googleapis.com
действительно новое имя хоста, которое мы должны использовать для получения контактов из браузера?
РЕДАКТИРОВАТЬ: Включая код, который делает запрос
const params = $.param({
alt: 'json',
access_token: 'MYTOKEN',
'max-results': 5000,
v: '3.0'
})
const url = `https://www.google.com/m8/feeds/contacts/default/thin?${params}` # when I change this to www.googleapis.com it works
$.get(url, responseHandler)
РЕДАКТИРОВАТЬ: Включая заголовки запроса на запрос опций CORS preflight, который мой браузер по какой-то причине отправляет:
Accept: text/html,application/xhtml+xm…plication/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.5
Access-Control-Request-Headers: x-csrf-token
Access-Control-Request-Method: GET
Cache-Control: no-cache
Connection: keep-alive
Host: www.google.com
Origin: https://localhost:3001
Pragma: no-cache
User-Agent: Mozilla/5.0 (Macintosh; Intel …) Gecko/20100101 Firefox/63.0
1 ответ
Благодаря комментариям @sideshowbarker мы выяснили, что у нас есть jQuery ajaxPrefilter, настроенный для добавления x-csrf-token
заголовок любого междоменного запроса AJAX. Это приводило к тому, что браузер отправлял запрос CORS preflight OPTIONS, который не удался.
В нашем случае источником заголовка x-csrf-token была зависимость, называемая ember-cli-rails-addon, которая добавляет x-csrf-token ко всем запросам. Здесь есть пиар для этого проекта, который решает эту проблему.