Почему я всегда получаю ошибку cors, что подстановочный знак * не разрешен, хотя я указал источник на сервере?

Я создал простой чат graphQL с сервером Apollo и клиентом Apollo.

Он также использует файлы cookie сеанса, поэтому я инициализировал сервер с пакетом npm cors следующим образом:

app.use(
  cors({
    credentials: true,
    origin: "http://localhost:3000"
  })
);

На стороне клиента я использую клиент apollo и создаю http-ссылку следующим образом:

const httpLink = new HttpLink({
  uri: "http://localhost:4000/graphql",
  credentials: "include"
});

Поэтому я включаю учетные данные, и сервер имеет источник моего клиента (который действительно http://локальный: 3000 — по умолчанию create-реагировать-приложение).

Когда я хочу выполнить запрос, я получаю эту ошибку в консоли браузера:

Access to fetch at 'http://localhost:4000/graphql' from origin 'http://localhost:3000' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.

Почему в заголовке ответа указано, что подстановочный знак * установлен, но в cors я установил конкретное происхождение, так что это не должно быть подстановочным знаком, верно?

Что мне здесь не хватает, ребята? Я также перезапустил оба сервера, конечно.

Когда я устанавливаю клиент следующим образом:

const httpLink = new HttpLink({
  uri: "http://localhost:4000/graphql",
  credentials: "same-origin"
});

Я не получаю сообщение об ошибке от cors, но я не получаю файл cookie с сервера. Файлы cookie работают, потому что на GraphQL Playground все работает как положено.

Если вы хотите увидеть полный код: https://github.com/SelfDevTV/graphql-простой-чат

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
6
0
3 544
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Проблема решена.

В моем index.js файле с сервера. Несколькими строками ниже я применяю экспресс-приложение в качестве промежуточного программного обеспечения к экземпляру сервера apollo следующим образом:

server.applyMiddleware({ app });

Но это переопределяет параметры cors, которые я установил выше.

Поэтому я должен назвать это так: server.applyMiddleware({ app, cors: false });

Теперь все работает отлично :)

Это просто отключение cors. Лучшим решением было бы настроить прокси для локальной разработки в вашем package.json "proxy": "http://localhost:4000/",, который указывает реагировать на прокси-порт 4000 через ваше приложение для разработки. Для производства вам необходимо объединить сервер и внешний интерфейс вместе.

Jake Luby 09.07.2019 16:24

Он действительно отключается? Потому что это будет означать, что учетные данные не будут переданы клиенту? То есть куки не работали бы, а они так делают? Мне установить этот прокси-сервер, который вы упомянули в package.json, из папки create-react-app или package.json сервера?

GeraltDieSocke 09.07.2019 16:30

Да, cors: false отключает cors, что не имеет ничего общего с учетными данными или файлами cookie. Это защита безопасности, которая гораздо лучше объяснена здесь: medium.com/@baphemot/understanding-cors-18ad6b478e2b Что касается прокси-сервера, вы помещаете его в свой реактивный package.json.

Jake Luby 09.07.2019 17:29

Хорошо, когда я установил этот прокси. Что конкретно мне делать дальше. Включите cors с помощью пакета cors следующим образом: app.use( cors({ credentials: true, origin: ["http://localhost:3000"] }) ); А также установите cors:true на экземпляре сервера apollo? А на клиенте я могу установить {credentials: "same-origin" }? Это правильно так? Обновлено: Так не работает. same-origin работает, но нет файла cookie. include та же ошибка cors с подстановочным знаком.

GeraltDieSocke 09.07.2019 17:33

Вам не нужно делать что-либо явно с обеих сторон, просто установите прокси на стороне реагирования, и он нажмет http://localhost:4000, как если бы он нажал http://localhost:3000. Вот официальные документы: facebook.github.io/create-react-app/docs/…

Jake Luby 09.07.2019 17:44

Другое дело, что я пробовал. * Установите прокси на package.json * отключите пакет cors * включите cors вот так на сервере: server.applyMiddleware({ app, cors: { credentials: true, origin: "http://localhost:3000" } }); Это работает, но не когда я устанавливаю origin: same-origin на клиенте, так что это все еще небезопасно для производства, когда я использую include верно?

GeraltDieSocke 09.07.2019 17:45

Реактивный прокси работает только в разработке. Для производства вы захотите обслуживать как реагирующую сборку, так и конечные точки API с одного и того же (экспресс?) веб-сервера, чтобы это не было запросом на перекрестное происхождение. Это не работает в среде разработки, потому что обычно вы начинаете реагировать с npm run start, а сервер — с чем-то вроде npm run server, и они не могут использовать один и тот же порт. Реагирующий прокси решает эту проблему. Для prod вам понадобится статическая сборка и обслуживайте ее оттуда, где вы обслуживаете API.

Jake Luby 09.07.2019 20:34

Вы нашли решение для этого? у меня точно такая же проблема

alexr89 02.03.2020 21:51

Привет, да, моя проблема решена, см. мое решение там.

GeraltDieSocke 02.03.2020 22:16

Некоторые комментарии здесь заставили меня немного обеспокоиться, что, возможно, обработка CORS просто отключена cors: false . Я протестировал его и убедился, что промежуточное ПО CORS приложения действительно вызывается для всех вызовов gql. Отличный совет.

dfl 04.01.2022 10:32

Вместо этого вы можете указать серверу Apollo, как настроить cors.

const corsOptions = {
  origin: "http://localhost:3000",
  credentials: true
}

server.applyMiddleware({
  app,
  cors: corsOptions
}) 

Затем вы можете полностью исключить промежуточное ПО Express Cors.

Это сработало для меня. Я думаю, что это должен быть принятый ответ.

jaimefps 24.06.2020 00:34

Когда я использовал http://localhost:3000 или true в качестве источника, это работало, но не когда я добавлял *, / или /* в конце URL-адреса, например. http://localhost:3000/. Я также добавил это как переменную в свой файл env.dev: CLIENT_URL=http://localhost:3000, а затем загрузил его в индекс сервера через origin: process.env.CLIENT_URL, что сработало хорошо.

James L. 02.10.2021 20:37

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