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 ко всем запросам. Здесь есть пиар для этого проекта, который решает эту проблему.

Другие вопросы по тегам