【问题标题】:React-router and nginx反应路由器和 nginx
【发布时间】:2017-10-12 14:23:00
【问题描述】:

我正在将我的 react 应用从 webpack-dev-server 转换到 nginx。

当我转到根 url “localhost:8080/login”时,我只是得到一个 404,在我的 nginx 日志中我看到它正在尝试获取:

my-nginx-container | 2017/05/12 21:07:01 [error] 6#6: *11 open() "/wwwroot/login" failed (2: No such file or directory), client: 172.20.0.1, server: , request: "GET /login HTTP/1.1", host: "localhost:8080"
my-nginx-container | 172.20.0.1 - - [12/May/2017:21:07:01 +0000] "GET /login HTTP/1.1" 404 169 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:53.0) Gecko/20100101 Firefox/53.0" "-"

我应该在哪里寻找修复?

我的路由器位在 react 中如下所示:

render(

  <Provider store={store}>
    <MuiThemeProvider>
      <BrowserRouter history={history}>
        <div>
          Hello there p
          <Route path="/login" component={Login} />
          <App>

            <Route path="/albums" component={Albums}/>

            <Photos>
              <Route path="/photos" component={SearchPhotos}/>
            </Photos>
            <div></div>
            <Catalogs>
              <Route path="/catalogs/list" component={CatalogList}/>
              <Route path="/catalogs/new" component={NewCatalog}/>
              <Route path="/catalogs/:id/photos/" component={CatalogPhotos}/>
              <Route path="/catalogs/:id/photos/:photoId/card" component={PhotoCard}/>
            </Catalogs>
          </App>
        </div>
      </BrowserRouter>
    </MuiThemeProvider>
  </Provider>, app);

我的 nginx 文件是这样的:

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;

    server {
        listen 8080;
        root /wwwroot;

        location / {
            root /wwwroot;
            index index.html;

            try_files $uri $uri/ /wwwroot/index.html;
        }


    }
}

编辑:

我知道大部分设置都有效,因为当我在没有登录的情况下转到 localhost:8080 时,我也会得到登录页面。这不是通过重定向到 localhost:8080/login - 这是一些反应代码。

【问题讨论】:

  • try_files 的参数应该是 URI 而不是路径名。试试看:try_files $uri $uri/ /index.html;
  • @RichardSmith 好的...我将其视为 index.html 文件的路径名。我已经尝试将其更改为您的建议 - 但得到相同的结果。 ## /wwwroot/login" failed (2: No such file or directory) ## 你还有其他建议吗。今晚我会深入研究...
  • @martin 你能解决这个问题吗?我们看到了同样的东西,但是里面已经有了 try_files 行。

标签: nginx react-router


【解决方案1】:

你的 nginx 配置中的 location 块应该是:

location / {
  try_files $uri /index.html;
}

问题是对 index.html 文件的请求有效,但您目前没有告诉 nginx 也将其他请求转发到 index.html 文件。

【讨论】:

  • 查看更多高级配置(缓存、404 用于丢失 .js、.css 文件等)gkedge.gitbooks.io/react-router-in-the-real/content/nginx.html
  • React Router 似乎根本不应该导致到服务器的往返......这可以在本地阻止吗?
  • 如果 nginx 不将请求路由到 index.html 文件,那么 React Router 内部的 JS 甚至永远不会知道该请求。这个答案将所有请求路由到 React,允许 React Router 处理所有请求。
  • 使用 package.json 中的默认主页设置也很重要,它使用服务器根目录。我已将其设置为 '.',(使用相对路径),但随后 nginx 尝试服务 /custompath/static/main.js,这显然会失败,给出一个非工作站点。
  • 只是提醒一下,确保您的配置实际上正在加载,我的配置与默认值冲突,只是被跳过。叹息
【解决方案2】:

这是我的解决方案

简单的尝试:

location / {
    root /var/www/mysite;
    try_files $uri /index.html;
}

不再尝试非 html 类型:

location / {
    root /var/www/mysite;
    set $fallback_file /index.html;
    if ($http_accept !~ text/html) {
        set $fallback_file /null;
    }
    try_files $uri $fallback_file;
}

不再尝试非 html 类型和目录(使 try_filesindex 和/或 autoindex 兼容):

location / {
    root /var/www/mysite;
    index index.html;
    autoindex on;
    set $fallback_file /index.html;
    if ($http_accept !~ text/html) {
        set $fallback_file /null;
    }
    if ($uri ~ /$) {
        set $fallback_file /null;
    }
    try_files $uri $fallback_file;
}

【讨论】:

    【解决方案3】:

    也许这不是这里的确切情况,但对于使用react-routerwebpack-dev-server 为他们的react 项目运行docker 容器的任何人,在我的情况下,我的nginx.conf 中有我需要的一切:

    server {
        listen 80;
        location / {
          root   /usr/share/nginx/html;
          index  index.html index.htm;
          try_files $uri $uri/ /index.html;
        } 
        error_page 404 /index.html;
        location = / {
          root /usr/share/nginx/html;
          internal;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
          root   /usr/share/nginx/html;
        }
      }
    

    但 nginx 仍然不会向根 / 发送 404 错误。查看容器后,我注意到/etc/nginx/conf.d/default.conf 中有一些配置会以某种方式覆盖我的配置,因此删除我的dockerfile 中的那个文件解决了这个问题:

    ...
    FROM nginx:alpine
    COPY --from=build /app/build /usr/share/nginx/html
    RUN rm /etc/nginx/conf.d/default.conf  # <= This line solved my issue
    COPY nginx.conf /etc/nginx/conf.d
    EXPOSE 80
    CMD ["nginx", "-g", "daemon off;"]
    

    【讨论】:

      【解决方案4】:

      这是在实时服务器中适合我的解决方案:

      我刚刚followed this tutorial 和基本的 Nginx 配置只是配置了位置块。

      location / {
          try_files $uri $uri/ /index.html;
      }
      

      【讨论】:

        【解决方案5】:

        如果您从子目录(例如 http://localhost:8080/jobs/)提供服务:

        使用你的 / 块如下:

        server {
            listen              8080;
            server_name         localhost;
            absolute_redirect   off;
            root                /usr/share/nginx/html;
            index               index.html;
        
            location / {
              expires         5m;
              add_header      Cache-Control "public";
              try_files $uri $uri/ /jobs/index.html;
            }
        
        }
        

        【讨论】:

          【解决方案6】:

          对我来说,在我添加根指令之前没有任何效果。这也适用于我使用反向代理来访问 /api/ 网络服务器端点。

          location / {
              root   /usr/share/nginx/html;
              try_files $uri /index.html;
          }
          

          【讨论】:

          • 有没有可能是 Express API 服务器?如果是这样,您介意分享您的配置/Dockerfile 吗?
          【解决方案7】:

          Nginx 会尝试在根目录中查找 index.html,如果您使用不同的位置,您可能需要将其添加到 try_files 指令中:

          所以而不是:

          location /MyLocation {
              root /var/www/html;
              try_files $uri /index.html;
          }
          

          你应该这样做:

          location /MyLocation {
              root /var/www/html;
              try_files $uri /MyLocation/index.html; # Make sure to add the folder to the path
          }
          

          通过将 MyLocation 添加到 try_files,您可以让 nginx 在重定向路由时使用正确的 index.html。

          【讨论】:

            【解决方案8】:

            0

            我知道这个问题已经被回答到死了,但是它并没有解决你想使用代理通道的浏览器路由器的问题,你不能使用 root。

            对我来说,解决方案非常简单。

            假设你有一个指向某个端口的 url。

            location / {
              proxy_pass http://127.0.0.1:30002/;
              proxy_set_header    Host            $host;
              port_in_redirect    off;
            }
            

            现在由于浏览器路由器的子路径已损坏。但是你知道子路径是什么。

            解决方案?对于子路径/contact

            # just copy paste.
            location /contact/ {
              proxy_pass http://127.0.0.1:30002/;
              proxy_set_header    Host            $host;
            }
            

            我尝试过的其他方法都无效,但这个简单的修复方法就像一个该死的魅力。

            【讨论】:

            • 当您不知道子路径时有什么解决方案?正在构建一个 CMS,用户可以在其中创建自己的导航
            【解决方案9】:

            我在使用服务工作者和这个确切的 nginx 配置的 create-react-app 方面遇到了一些问题。发布站点的新版本后,服务人员将重新获取 JS 并发送 index.html 文件而不是 404。所以我的 nginx 配置的更新版本是这样的:

            location / {
                    try_files $uri /index.html;
            }
            
            location /static/ {
                    try_files $uri =404;
            }
            

            它确保 /static/ 中的任何内容都不会返回 index.html。

            【讨论】:

              【解决方案10】:

              以下是我采取的一些步骤,如果您刚开始,可能会对您有所帮助

              1. 在 SSH 中需要使用 cd .. 返回到 root / 然后你应该在 /
              2. 然后找到前面通常位于 /etc/nginx/sites-available/{yoursitename or default}cd的.conf文件导航到它
              3. 使用nanovim 编辑该文件我使用Vim 就像这样vi {your site.conf}
              4. 这里是应该工作的整个文件的内容
              server {
                      listen       80;
                      server_name www.yourDomainName.com, yourDomainName.com;
                      location / {
                          root   /usr/share/nginx/{location of the build of your react project};
                          index  index.html index.htm;
                          
                          try_files $uri $uri/ /index.html;
              
                          passenger_enabled on;
                      }
                      error_page   500 502 503 504  /50x.html;
                      location = /50x.html {
                          root   html;
                      }
              }
              

              【讨论】:

                【解决方案11】:

                我正在处理同样的问题,我认为这是一个配置错误,但不是。我正在将 conf 文件复制到 /etc/nginx/conf.d/ 文件夹。这在开发中有效,但在构建版本中会导致该问题。当路由失败时,nginx 不会回退到索引。

                只需将conf文件复制到正确的文件夹:/etc/nginx/conf.d/default.conf

                示例 Dockerfile 指令: COPY .docker/prod/nginx.conf /etc/nginx/conf.d/default.conf

                希望对你有帮助。

                【讨论】:

                  【解决方案12】:
                  location / {
                      root /path/to/root/directory/of/staticfiles;
                      index index.html;
                      try_files $uri /index.html;
                  }
                  

                  【讨论】:

                  • 在 Stack Overflow 上不鼓励仅使用代码的答案,因为它们没有解释它如何解决问题。请编辑您的答案以解释此代码的作用以及它如何改进现有的投票答案,以便它对 OP 以及其他有类似问题的用户有用。
                  猜你喜欢
                  • 2019-11-14
                  • 2017-09-07
                  • 1970-01-01
                  • 2016-08-18
                  • 2017-06-14
                  • 2018-09-20
                  • 1970-01-01
                  • 2020-09-30
                  • 2020-11-01
                  相关资源
                  最近更新 更多