Я нашел решение, которое есть в ответах.
Я знаю, что вопросы о CORS задавались много раз. В данном случае я хочу понять обоснование такой политики, потому что совсем не понимаю. Я также ищу обходной путь не на стороне сервера.
Я пытаюсь написать расширение для Firefox, которое вызывает API LeetCode. Например, это запрос на выборку, который я пытаюсь выполнить в JavaScript.
let url = `https://leetcode.com/graphql/?query=query{
allQuestionsCount {
difficulty
count
}
matchedUser(username: "lee215") {
username
}
}`
const response = await fetch(url);
var data = await response.json();
Если я просто попытаюсь запустить этот код в своем браузере, я получу ошибку CORS, Reason: CORS header 'Access-Control-Allow-Origin' missing.
Если я временно отключу CORS с помощью расширения типа CORS Everywhere, код будет работать. Моя проблема в том, что я не хочу этого делать. Более серьезная проблема заключается в том, что CORS Everywhere, похоже, не работает в среде расширений (только на простой странице браузера).
Наверное, я просто запутался, почему leetcode.com, работающий в моем браузере, может вызвать API, а я получаю ошибку? Зачем эта политика останавливает злоумышленников, если любой может прочитать ответ API, а веб-страница хоста может выполнить с его помощью JS-код в моем браузере? Есть ли у меня способ обойти это?
В источнике (leetcode) не указано, что их API можно использовать на всех доменах, поэтому браузер блокирует его. Да, расширения могут обойти эту проблему, но они должны быть включены пользователем.... это функция безопасности. Если произойдет сбой из-за ошибки CORS, JS также не будет иметь доступа к телу.
I'm also looking for any workaround that isn't on the server side. Нет ни одного, за исключением хакерских расширений для браузера. В этом суть CORS. why can leetcode.com, running in my browser, call the API Потому что вы используете их сайт для вызова их API. CORS вмешивается, когда вы вызываете сторонний API со своего сайта без явного разрешения этой третьей стороны через свою конфигурацию CORS.
Если я создам HTML-файл на своем компьютере и открою его, код не будет работать (или если я запущу его в консоли на любой странице, кроме leetcode.com). Моя главная проблема в том, что расширение не работает даже на leetcode.com. Я думаю, что среды полностью разделены.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Важно помнить, что SOP (Same Origin Policy) влияет на ситуацию на уровне браузера. Мой браузер, если я открою вредоносный сайт, не позволит javascript на вредоносном сайте получить доступ к данным с другого сайта, чтобы заблокировать кражу данных, которые я мог ввести на втором сайте, или выполнение действий с учетной записью, вошедшей в систему. на втором сайте. Второй сайт может использовать заголовки CORS, чтобы сообщить браузеру, что данные можно использовать, но в противном случае вам не повезло.
Расширения отличаются от веб-сайтов. Поскольку их установка — это выбор пользователя, а не что-то, что запускается, как только пользователь загружает страницу, им доверяют больше. Расширение может получить доступ к другим веб-сайтам, но вам необходимо следовать некоторым правилам. На следующей странице содержится дополнительная информация об использовании CORS в расширении:
Мне удалось решить эту проблему на основе ответа dmfr56, но мне пришлось повозиться, поэтому я собираюсь объяснить, что я сделал здесь. Многие ответы на этот вопрос актуальны.
Я мог заставить это работать только в Manifest v2 в Firefox. Я не пробовал это в Chrome, и ни одно из простых исправлений или исправлений фоновых сценариев для Manifest v3 мне не помогло.
Фоновые сценарии могут обойти ограничения CORS (по сути, это просто еще один сценарий в вашем дополнении). Вам нужно поместить прослушиватель в фоновый скрипт:
фон.js:
browser.runtime.onMessage.addListener(
function(url, sender, onSuccess) {
fetch(url).then(response => onSuccess(response));
return true;
}
);
Затем добавьте скрипт в свой манифест:
"background": {
"scripts": ["background.js"]
}
Также в манифесте добавьте разрешения для сайта, к которому вы обращаетесь:
"permissions": [
"https://leetcode.com/graphql"
]
Теперь, когда вы хотите получить доступ к ограниченному API CORS в основном файле JavaScript, используйте это:
основной.js:
let url == "your url here"
browser.runtime.sendMessage(url, data => received_data(data));
function received_data(data) {
// process returned data
}
Извлечение будет происходить асинхронно, и ваша функция «received_data» будет иметь обратный вызов, когда данные будут готовы.
Последнее замечание: у меня это работает в Manifest v3 (в Firefox). Вам необходимо внести пару изменений в форматирование манифеста, которые описаны в документации. Проблема, с которой я столкнулся, заключается в том, что в Firefox Manifest v3 разрешения хоста не являются обязательными и отключены по умолчанию (не очень хорошая политика, по моему мнению). Поэтому обязательно перейдите к управлению расширениями и включите необходимые вам разрешения.
«Если я просто попытаюсь запустить этот код в своем браузере» — где именно вы это запускаете? Если вы запустите его на странице leetcode.com (например, в консоли devtools), он будет работать нормально.