CORS Missing Allow Origin: почему веб-страница может вызвать API в моем браузере, но я не могу вызвать его без ошибки CORS?

Я нашел решение, которое есть в ответах.

Я знаю, что вопросы о 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.com (например, в консоли devtools), он будет работать нормально.

Bergi 19.02.2024 17:20

В источнике (leetcode) не указано, что их API можно использовать на всех доменах, поэтому браузер блокирует его. Да, расширения могут обойти эту проблему, но они должны быть включены пользователем.... это функция безопасности. Если произойдет сбой из-за ошибки CORS, JS также не будет иметь доступа к телу.

Blair 19.02.2024 17:24
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.
Rory McCrossan 19.02.2024 17:24

Если я создам HTML-файл на своем компьютере и открою его, код не будет работать (или если я запущу его в консоли на любой странице, кроме leetcode.com). Моя главная проблема в том, что расширение не работает даже на leetcode.com. Я думаю, что среды полностью разделены.

burningpocket 19.02.2024 17:28
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
4
514
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Важно помнить, что SOP (Same Origin Policy) влияет на ситуацию на уровне браузера. Мой браузер, если я открою вредоносный сайт, не позволит javascript на вредоносном сайте получить доступ к данным с другого сайта, чтобы заблокировать кражу данных, которые я мог ввести на втором сайте, или выполнение действий с учетной записью, вошедшей в систему. на втором сайте. Второй сайт может использовать заголовки CORS, чтобы сообщить браузеру, что данные можно использовать, но в противном случае вам не повезло.

Расширения отличаются от веб-сайтов. Поскольку их установка — это выбор пользователя, а не что-то, что запускается, как только пользователь загружает страницу, им доверяют больше. Расширение может получить доступ к другим веб-сайтам, но вам необходимо следовать некоторым правилам. На следующей странице содержится дополнительная информация об использовании CORS в расширении:

Расширение CORS Chrome с манифестом версии 2

Мне удалось решить эту проблему на основе ответа 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 разрешения хоста не являются обязательными и отключены по умолчанию (не очень хорошая политика, по моему мнению). Поэтому обязательно перейдите к управлению расширениями и включите необходимые вам разрешения.

burningpocket 21.02.2024 18:19

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