CORS错误在访问Docker容器中的NodeJS Express API时发生。

huangapple go评论125阅读模式
英文:

CORS error when accessing NodeJS express api in Docker container

问题

在主机上运行时,我的NodeJS API和NextJS应用程序位于单独的Docker容器中,一切都正常工作,但在Docker容器内运行时,出现了CORS错误。

我的Express配置在API中如下:

  1. app.use(cors({
  2. credentials: true,
  3. origin: 'http://localhost:3000/' // 允许前端运行在端口3000上
  4. }));
  5. app.use(cookieParser());
  6. app.use(bodyParser.json());
  7. app.use(urlencoded({ extended: true }));
  8. app.use(json());
  9. app.enable("trust proxy");
  10. app.use(methodOverride());

在前端NextJS axios配置中如下:

  1. const axiosInstance = axios.create({ baseURL: 'http://localhost:4000/', withCredentials: true });

当我从主机机器上运行API时,一切正常,但在Docker中使用相同的配置时出现CORS错误。

英文:

I have NodeJS api and NextJS application in Separate docker containers when I'm in host machine its working fine, but when I'm running inside docker containers its giving CORS error.

My express config in API

  1. app.use(cors({
  2. credentials: true,
  3. origin: 'http://localhost:3000/' // Allowing front-end running port 3000
  4. }));
  5. app.use(cookieParser());
  6. app.use(bodyParser.json());
  7. app.use(urlencoded({ extended: true }));
  8. app.use(json());
  9. app.enable("trust proxy");
  10. app.use(methodOverride());

In front-end APP NextJS axios config

  1. const axiosInstance = axios.create({ baseURL: 'http://localhost:4000/', withCredentials: true });

CORS错误在访问Docker容器中的NodeJS Express API时发生。

CORS错误在访问Docker容器中的NodeJS Express API时发生。

Its woking fine when im running API from host machine, with same configuration its giving CORS error in Docker.

答案1

得分: 1

以下是翻译好的部分:

"我能看到你的API配置似乎是正确的,但在你的NextJS中创建pages/api/whatever.js,然后从处理程序中调用你的API。

  1. import axios from 'axios';
  2. axios.defaults.withCredentials = true;
  3. export default async function handler(req, res){
  4. try {
  5. const response = axios.post('http://localhost:4000/<your_login_api_URL>', req.body)
  6. }catch(error) {
  7. // 处理错误
  8. }
  9. }"
  10. 这将有效并且是一种更安全的方式来隐藏你的后端API调用不让前端直接访问
  11. <details>
  12. <summary>英文:</summary>
  13. As i can see your API configuration seems correct, but in your NextJS create pages/api/whatever.js and call your API from handler
  14. import axios from &#39;axios&#39;;
  15. axios.defaults.withCredentials = true;
  16. export default async function handler(req, res){
  17. try {
  18. const response = axios.post(&#39;http://localhost:4000/&lt;your_login_api_URL&gt;&#39;, req.body)
  19. }catch(error) {
  20. // handle error here
  21. }
  22. }
  23. this will work and its safer way to mask your back end API calls from front end.
  24. </details>
  25. # 答案2
  26. **得分**: 0
  27. 将每个`localhost` + `port`添加到`cors`选项中_我只是为了示例留下了一些其他选项与您的问题无关_):
  28. ```javascript
  29. // 跨域中间件选项
  30. const options: cors.CorsOptions = {
  31. allowedHeaders: [
  32. 'X-ACCESS_TOKEN',
  33. 'Access-Control-Allow-Origin',
  34. 'Authorization',
  35. 'Origin',
  36. 'x-requested-with',
  37. 'Content-Type',
  38. 'Content-Range',
  39. 'Content-Disposition',
  40. 'Content-Description',
  41. ],
  42. credentials: true,
  43. methods: 'GET,HEAD,OPTIONS,PUT,PATCH,POST,DELETE',
  44. origin: [
  45. 'http://localhost:5001',
  46. 'http://localhost:50000',
  47. ],
  48. preflightContinue: false,
  49. };
  50. const app = express();
  51. const corsOpts = cors(options);
  52. // 添加跨域中间件
  53. app.use(corsOpts);
英文:

Add each localhost + port to the cors options (I left some other options just for example, not relevant to your question though):

  1. //options for cors midddleware
  2. const options: cors.CorsOptions = {
  3. allowedHeaders: [
  4. &#39;X-ACCESS_TOKEN&#39;,
  5. &#39;Access-Control-Allow-Origin&#39;,
  6. &#39;Authorization&#39;,
  7. &#39;Origin&#39;,
  8. &#39;x-requested-with&#39;,
  9. &#39;Content-Type&#39;,
  10. &#39;Content-Range&#39;,
  11. &#39;Content-Disposition&#39;,
  12. &#39;Content-Description&#39;,
  13. ],
  14. credentials: true,
  15. methods: &#39;GET,HEAD,OPTIONS,PUT,PATCH,POST,DELETE&#39;,
  16. origin: [
  17. &#39;http://localhost:5001&#39;,
  18. &#39;http://localhost:50000&#39;,
  19. ],
  20. preflightContinue: false,
  21. };
  22. const app = express();
  23. const corsOpts = cors(options);
  24. //add cors middleware
  25. app.use(corsOpts);
  26. </details>
  27. # 答案3
  28. **得分**: 0
  29. 这是常见的问题,有许多解决方案。
  30. 正确的解决方案取决于您的需求。更简单的解决方案是在运行Docker容器时使用NGINX作为反向代理。
  31. **NGINX Docker示例**
  32. ```dockerfile
  33. FROM nginx:alpine
  34. WORKDIR /etc/nginx
  35. COPY ./nginx.conf ./conf.d/default.conf
  36. EXPOSE 80
  37. ENTRYPOINT ["nginx"]
  38. CMD ["-g", "daemon off;"]

将其构建为cors

  1. docker build -t cors .

最后确保nginx.conf允许来自请求的源

  1. add_header 'Access-Control-Allow-Origin' '*';

NGINX配置示例

  1. upstream api {
  2. # 可以是host.docker.internal - 适用于Docker的Mac/Windows - 主机本身
  3. # 可以是您的API在适当的域中
  4. # 可以是同一网络中的其他容器,如container_name:port
  5. server url:port;
  6. }
  7. server {
  8. listen 80;
  9. server_name localhost;
  10. location / {
  11. if ($request_method = 'OPTIONS') {
  12. add_header 'Access-Control-Max-Age' 1728000;
  13. add_header 'Access-Control-Allow-Origin' '*';
  14. add_header 'Access-Control-Allow-Headers' 'Authorization,Accept,Origin,DNT,X-CustomHeader,Keep-Alive,User-Agent,
  15. X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
  16. add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT,DELETE,PATCH';
  17. add_header 'Content-Type' 'application/json';
  18. add_header 'Content-Length' 0;
  19. return 204;
  20. }
  21. add_header 'Access-Control-Allow-Origin' '*';
  22. add_header 'Access-Control-Allow-Headers' 'Authorization,Accept,Origin,DNT,X-CustomHeader,Keep-Alive,User-Agent,
  23. X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
  24. add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT,DELETE,PATCH';
  25. proxy_pass http://api/;
  26. }
  27. }
英文:

This is common issue many solutions.

The correct solution depends on your requirements.The simpler solution is to run the docker container with NGINX acting as reverse proxy.

Example of nginx docker

  1. FROM nginx:alpine
  2. WORKDIR /etc/nginx
  3. COPY ./nginx.conf ./conf.d/default.conf
  4. EXPOSE 80
  5. ENTRYPOINT [ &quot;nginx&quot; ]
  6. CMD [ &quot;-g&quot;, &quot;daemon off;&quot; ]

Build it as cors

  1. docker build -t cors .

Finally make sure that nginx.conf allowing origins from request

  1. add_header &#39;Access-Control-Allow-Origin&#39; &#39;*&#39;;

Example of nginx.config

  1. upstream api {
  2. # Could be host.docker.internal - Docker for Mac/Windows - the host itself
  3. # Could be your API in a appropriate domain
  4. # Could be other container in the same network, like container_name:port
  5. server url:port;
  6. }
  7. server {
  8. listen 80;
  9. server_name localhost;
  10. location / {
  11. if ($request_method = &#39;OPTIONS&#39;) {
  12. add_header &#39;Access-Control-Max-Age&#39; 1728000;
  13. add_header &#39;Access-Control-Allow-Origin&#39; &#39;*&#39;;
  14. add_header &#39;Access-Control-Allow-Headers&#39; &#39;Authorization,Accept,Origin,DNT,X-CustomHeader,Keep-Alive,User-Agent,
  15. X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range&#39;;
  16. add_header &#39;Access-Control-Allow-Methods&#39; &#39;GET,POST,OPTIONS,PUT,DELETE,PATCH&#39;;
  17. add_header &#39;Content-Type&#39; &#39;application/json&#39;;
  18. add_header &#39;Content-Length&#39; 0;
  19. return 204;
  20. }
  21. add_header &#39;Access-Control-Allow-Origin&#39; &#39;*&#39;;
  22. add_header &#39;Access-Control-Allow-Headers&#39; &#39;Authorization,Accept,Origin,DNT,X-CustomHeader,Keep-Alive,User-Agent,
  23. X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range&#39;;
  24. add_header &#39;Access-Control-Allow-Methods&#39; &#39;GET,POST,OPTIONS,PUT,DELETE,PATCH&#39;;
  25. proxy_pass http://api/;
  26. }
  27. }

答案4

得分: -1

Add this line to your package.json file. then rebuild your container and start the app.

  1. "proxy": "http://localhost:4000",
英文:

Add this line to your package.json file. then rebuild your container and start the app.

  1. &quot;proxy&quot;: &quot;http://localhost:4000&quot;,

huangapple
  • 本文由 发表于 2023年1月5日 13:18:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/75014128.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定