Я пытался выполнить вызов API (nodejs с экспресс-запуском на локальном хосте) из реагирующего приложения, работающего в браузере, через локальный сервер разработки (сервер разработки веб-пакета). Все работало хорошо, пока я не попытался вызвать API. Они оба работают на разных портах.
Я попытался добавить заголовки cors (рекомендуется MDN) как к почтовому вызову (из приложения в браузере), так и к ответу от Nodejs API, но ни один из них не решил проблему.
Код для вызова API (в браузере):
const headers = {
'Content-Type': 'application/json',
'access-token': '',
'Access-Control-Allow-Origin': '*',
}
export default async () => {
try {
const body = JSON.stringify({
test: true,
})
const response = await fetch('http://localhost:1337/internal/provider/check_email_exist', {
method: 'POST',
headers,
body,
})
console.info(response)
} catch (e) {
return e
}
}
Промежуточное ПО API (в nodejs):
// Verify All Requests
app.use(VerifyToken)
// Compress
app.use(compression())
// Helmet middlware
app.use(helmet())
// Body Parser
app.use(bodyParser.urlencoded({
extended: false,
}))
app.use(bodyParser.json())
Ожидаемый результат — просто дать код состояния 200 и ответить данными.
Фактический результат:
OPTIONS http://localhost:1337/internal/provider/check_email_exist 404 (Not Found)
Access to fetch at 'http://localhost:1337/internal/provider/check_email_exist' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
Сервер, на который вы отправляете запрос, должен быть настроен для ответа на запросы OPTIONS с ответом 200 OK. Прямо сейчас он отвечает ошибкой 404 на запрос CORS preflight OPTIONS, который отправляет ваш браузер. Таким образом, у вас еще нет сервера с должным образом включенным CORS.





Поскольку вы используете webpack-dev-server, вы можете использовать опцию proxyDevServerProxy.
Ваша конфигурация будет выглядеть так:
// webpack.config.js
devServer: {
proxy: {
'/internal': 'http://localhost:1337'
}
}
Поскольку я не вижу ваших маршрутов express по вашему вопросу, я размышляю о прокси-маршруте, если ваш API живет на конечной точке /internal, тогда вам следует изменить свой код React следующим образом:
const response = await fetch('/internal/provider/check_email_exist', {
method: 'POST',
headers,
body,
})
Как видите, я пропустил https://localhost:1337, потому что опция proxy из webpack-dev-server справится с этим и перенаправит на http://localhost:1337. Надеюсь, что это поможет вам. Привет, Зигфрид.
РЕДАКТИРОВАТЬ
Как указано в комментарии к вашему вопросу, вы должны установить заголовки на своем сервере express, а не на клиенте, для этой задачи вы можете использовать пакет cors-middleware.
Возможно, это может помочь, если вы столкнетесь с ошибками предварительной проверки.
Моя полная конфигурация:
const cors = require('cors');
const express = require('express');
const { createProxyMiddleware: proxy } = require('http-proxy-middleware');
...
const logLevel = 'info';
const ip = require('ip').address();
const proxyOptions = {
xfwd: true,
target,
changeOrigin: true,
logLevel,
cookieDomainRewrite: {
'*': 'localhost',
},
headers: {
'X-Forwarded-For': ip,
'X-Node': 'true',
},
};
const backNginxApp = express();
backNginxApp.use(
cors({
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
origin: 'http://localhost:3000',
optionsSuccessStatus: 200,
credentials: true,
})
);
backNginxApp.use('/api', proxy(proxyOptions));
API: const target = 'https://someapi.com'
Локальная разработка работает по адресу: http://localhost:3000
Заголовок
Access-Control-Allow-Originдолжен исходить от сервера, а не от клиента. Вы можете попробовать использовать модульcors(app.use(cors())), чтобы это заработало, но я предлагаю вам прочитать о CORS и о том, как он используется для защиты пользователей веб-браузера. Также похоже, что вы не реализовали маршрут для/internal/provider/check_email_exist, поэтому запрос в целом не работает.