【问题标题】:nextjs axios requests inside getServerSideProps always return 404 after deployment with nginx使用 nginx 部署后,getServerSideProps 中的 nextjs axios 请求总是返回 404
【发布时间】:2022-01-11 13:46:58
【问题描述】:

我在带有 nodejs 后端的 ec2 实例上运行 nextjs 应用程序

当应用程序在 useEffect 内部发出 axios 请求时,它可以正常工作,但是当应用程序从 getServersideProps 函数内部发送请求时,它会失败并返回 404 状态码,并且请求根本没有到达后端。

这是 nginx 文件

server {
server_name frontend.domain.com;
location / {
    proxy_pass http://localhost:3000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-Port $server_port;

    # we need to remove this 404 handling
    # because of Next's error handling and _next folder
    # try_files $uri $uri/ =404;
}

listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/frontend.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/frontend.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}

server {
    server_name api.domain.com;
    location / {
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_cache_bypass $http_upgrade;
        proxy_pass         http://localhost:8080;
    }


    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/frontend.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/frontend.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}

这是 axios 的配置:

    const configModified = {
  baseURL: 'https://api.domain.com',
  withCredentials: true,
  headers:{},
  adapter: cache.adapter
  // global customizations
}
    export const request = (request) => {
  const source = axios.CancelToken.source();
  return {
    request: axios({ ...configModified, ...request}, cancelToken: source.token }),
    source
  }
}

它按预期在 localhost 上运行,但部署后请求仅在 getServerSideProps 函数中失败

【问题讨论】:

  • getServerSideProps 是一个在 nodejs 服务器上执行的函数 .. 如果您通过 nginx 将应用程序部署为静态,您将不再使用 nodejs 服务器来呈现您的应用程序 .. 它在开发模式下工作因为开发设置通过 nodejs 为应用程序提供服务
  • 我已经部署了带有服务器的应用程序,而不是作为静态站点,并且总是调用 getServerSideProps 函数,问题不在于函数本身,而在于其中的 http 请求。
  • 在 prod 环境中,你有没有安慰过请求并通过邮递员放置它以检查是否返回 404 ?即``` const source = axios.CancelToken.source(); return { request: axios({ ...configModified, ...request}, cancelToken: source.token }), source }``` - 什么是在应用程序之外构建的源,它仍然失败吗?跨度>
  • 你确定你的后端端口还是3000?
  • @JSEvgeny 后端正在工作,但不是来自服务器端请求

标签: node.js reactjs nginx axios next.js


【解决方案1】:

您必须根据您在服务器或客户端上修改您的 axios 实例。

export default ({ req }) => {
  if (typeof window === "undefined") {
    // We are on the server
    return axios.create({
      baseURL:
        "http://ingress-nginx-controller.ingress-nginx.svc.cluster.local",
      headers: req.headers,
    });
  } else {
    // We must be on the browser
    return axios.create({
      baseUrl: "https://api.domain.com",
      // if it causes error
      //   baseUrl: "/"
    });
  }
};

然后当你在服务器上时,传递上下文对象

export const getServerSideProps = async (context) => {
  const client = buildClient(context);
  ...
};

【讨论】:

  • 已经正常工作了,在本地服务器端,无需修改
  • 这个baseURL 在服务器端是什么意思? http://ingress-nginx-controller.ingress-nginx.svc.cluster.local
  • @GhyathDarwish 什么是api.domain.com
猜你喜欢
  • 2013-03-11
  • 1970-01-01
  • 2023-02-18
  • 1970-01-01
  • 1970-01-01
  • 2022-11-24
  • 2020-03-15
  • 2023-02-24
  • 2021-05-17
相关资源
最近更新 更多