从 React 应用程序向使用 pm2 的 Express 服务器发出请求时获取 "Reason: CORS request did not succeed"
Getting "Reason: CORS request did not succeed" while making request from a React app to an Express server that is up with pm2
所以我创建了一个 MERN 堆栈 Web 应用程序并且我正在使用 docker。一张图片用于我的 React 应用程序,一张图片用于 Express 应用程序。我的数据库仍在生产阶段,它在 Mlab 上。它可能不相关,但我想提供完整的信息以获得我的确切答案。这是我的 docker 配置文件:
后端 Dockerfile:
FROM node
WORKDIR /app
COPY package.json .
COPY package-lock.json .
RUN npm install pm2 -g
RUN npm install
RUN npm audit fix
COPY . .
COPY .env .
EXPOSE 2424
CMD ["npm","run","server"]
前面的 Dockerfile:
FROM node as builder
RUN mkdir -p /app
RUN chmod -R 777 /app
WORKDIR /app
ENV PATH /app/node_modules/.bin:$PATH
COPY package.json .
RUN npm install
COPY . .
COPY .env .
FROM nginx:stable-alpine
COPY --from=builder /app/build /usr/share/nginx/html
RUN rm /etc/nginx/conf.d/default.conf
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
和我的 docker-撰写文件:
version: "3"
networks:
now-net:
driver: bridge
services:
nowfront:
container_name: frontapp
build:
context: ./front
dockerfile: ./Docker/Dockerfile
volumes:
- "./front:/app"
- "/app/node_modules"
ports:
- 60:80
stdin_open: true
tty: true
restart: always
environment:
- CHOKIDAR_USEPOLLING=true
networks:
- now-net
backend:
container_name: backapp
restart: always
stdin_open: true
tty: true
build:
context: ./backend
dockerfile: Dockerfile
volumes:
- "./backend:/app"
- "/app/node_modules"
ports:
- 40:2424
networks:
- now-net
我的服务器正在监听 40 端口,front 正在监听 60 端口。它们都在同一台服务器上。
例如 HTTP://222.222.22.22:40 和 HTTP://222.222.22.22:60
我正在使用 pm2 运行 服务器使用“pm2 start app.js”。
在我的 express 应用程序中,我允许使用 cors npm 模块的所有来源:
app.use(cors({ origin: "http://222.222.22.22:60", credentials: true }));
app.use(fileupload({ useTempFiles: true }));
app.use(express.json({ limit: "200mb" }));
app.use(express.urlencoded({ extended: true, limit: "200mb" }));
在使用 pm2 之前,一切正常。使用 pm2 后,每次向后端发出请求时都会出现此错误。
例如,我在 Firefox 开发工具中收到此错误:
“跨源请求被阻止:同源策略不允许在 http://222.222.22.22:40/api/instruments/get-all-instruments-public 读取远程资源。(原因:CORS 请求未成功)”
并在“网络”选项卡中:
Firefox network tab
我这样发送这个特定请求:
export const getAllInstrumentsPublic = () => (dispatch) => {
axios
.get(`${uri.BaseURI}/api/instruments/get-all-instruments-public`)
.then((result) => {
const instruments = result.data;
dispatch({
type: types.GET_ALL_INSTRUMENTS,
payload: instruments,
});
})
.catch((err) => {
dispatch({
type: types.GET_ERROR,
payload: err.response ? err.response : {},
});
});
};
现在,问题很简单了。我做错了什么?
您是否已验证您服务器上的端点在其响应中确实将 "Access-Control-Allow-Origin"
header 设置为正确的地址?
您也可以尝试将其设置为 '*'
而不是 IP 地址,以验证它是否正常工作。
PS:我认为您 docker-compose 文件中的前端服务没有正确缩进,而后端服务是。
所以我再次将 Dockerfile 和 package.json 更改为 运行 带有 nodemon 的服务器,现在它工作正常。真奇怪。因为使用 pm2 是如此简单明了,我想在生产中使用 pm2 这样服务器才可靠。如果有人能为我的问题提出完整的解决方案,我将不胜感激。
所以我创建了一个 MERN 堆栈 Web 应用程序并且我正在使用 docker。一张图片用于我的 React 应用程序,一张图片用于 Express 应用程序。我的数据库仍在生产阶段,它在 Mlab 上。它可能不相关,但我想提供完整的信息以获得我的确切答案。这是我的 docker 配置文件:
后端 Dockerfile:
FROM node
WORKDIR /app
COPY package.json .
COPY package-lock.json .
RUN npm install pm2 -g
RUN npm install
RUN npm audit fix
COPY . .
COPY .env .
EXPOSE 2424
CMD ["npm","run","server"]
前面的 Dockerfile:
FROM node as builder
RUN mkdir -p /app
RUN chmod -R 777 /app
WORKDIR /app
ENV PATH /app/node_modules/.bin:$PATH
COPY package.json .
RUN npm install
COPY . .
COPY .env .
FROM nginx:stable-alpine
COPY --from=builder /app/build /usr/share/nginx/html
RUN rm /etc/nginx/conf.d/default.conf
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
和我的 docker-撰写文件:
version: "3"
networks:
now-net:
driver: bridge
services:
nowfront:
container_name: frontapp
build:
context: ./front
dockerfile: ./Docker/Dockerfile
volumes:
- "./front:/app"
- "/app/node_modules"
ports:
- 60:80
stdin_open: true
tty: true
restart: always
environment:
- CHOKIDAR_USEPOLLING=true
networks:
- now-net
backend:
container_name: backapp
restart: always
stdin_open: true
tty: true
build:
context: ./backend
dockerfile: Dockerfile
volumes:
- "./backend:/app"
- "/app/node_modules"
ports:
- 40:2424
networks:
- now-net
我的服务器正在监听 40 端口,front 正在监听 60 端口。它们都在同一台服务器上。 例如 HTTP://222.222.22.22:40 和 HTTP://222.222.22.22:60 我正在使用 pm2 运行 服务器使用“pm2 start app.js”。 在我的 express 应用程序中,我允许使用 cors npm 模块的所有来源:
app.use(cors({ origin: "http://222.222.22.22:60", credentials: true }));
app.use(fileupload({ useTempFiles: true }));
app.use(express.json({ limit: "200mb" }));
app.use(express.urlencoded({ extended: true, limit: "200mb" }));
在使用 pm2 之前,一切正常。使用 pm2 后,每次向后端发出请求时都会出现此错误。 例如,我在 Firefox 开发工具中收到此错误:
“跨源请求被阻止:同源策略不允许在 http://222.222.22.22:40/api/instruments/get-all-instruments-public 读取远程资源。(原因:CORS 请求未成功)”
并在“网络”选项卡中: Firefox network tab
我这样发送这个特定请求:
export const getAllInstrumentsPublic = () => (dispatch) => {
axios
.get(`${uri.BaseURI}/api/instruments/get-all-instruments-public`)
.then((result) => {
const instruments = result.data;
dispatch({
type: types.GET_ALL_INSTRUMENTS,
payload: instruments,
});
})
.catch((err) => {
dispatch({
type: types.GET_ERROR,
payload: err.response ? err.response : {},
});
});
};
现在,问题很简单了。我做错了什么?
您是否已验证您服务器上的端点在其响应中确实将 "Access-Control-Allow-Origin"
header 设置为正确的地址?
您也可以尝试将其设置为 '*'
而不是 IP 地址,以验证它是否正常工作。
PS:我认为您 docker-compose 文件中的前端服务没有正确缩进,而后端服务是。
所以我再次将 Dockerfile 和 package.json 更改为 运行 带有 nodemon 的服务器,现在它工作正常。真奇怪。因为使用 pm2 是如此简单明了,我想在生产中使用 pm2 这样服务器才可靠。如果有人能为我的问题提出完整的解决方案,我将不胜感激。