React-Router和Nginx


107

我正在将我的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" "-"

我应该在哪里寻找解决方法?

我的路由器位反应如下:

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-这是一些响应代码。


1
要使用的参数try_files应该是URI,而不是路径名。试试:try_files $uri $uri/ /index.html;
理查德·史密斯

@RichardSmith好吧...我将它视为index.html文件的路径名。我尝试将其更改为您的建议-但得到相同的结果。## / wwwroot / login“失败(2:没有这样的文件或目录)##您还有其他建议吗?我会深入研究它
马丁

@martin您能解决这个问题吗?我们看到的是同一件事,但是那里已经有try_files行。
比利·弗格森

Answers:


240

nginx配置中的位置块应为:

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

问题在于,对index.html文件的请求可以正常工作,但是您当前并没有在告诉nginx将其他请求转发到index.html文件。


8
请检查此内容以获取更高级的配置(缓存,404缺失的.js,.css文件等)。gkedge.gitbooks.io/react
Gianfranco P.

看来React Router根本不应该导致服务器往返...这可以在本地受到阻碍吗?
Scotty H

如果nginx没有将请求路由到index.html文件,那么React Router中的JS将永远不会意识到该请求。这个答案将所有请求路由到React,从而允许React Router处理所有请求。
Toby

使用package.json中的默认主页设置(使用服务器根目录)也很重要。我已经将其设置为“。”(使用相对路径),但是随后nginx尝试提供/custompath/static/main.js,这显然会失败,从而导致无法正常工作的站点。
boerre

请注意,请确保您的配置实际上已被加载,我的配置与默认设置冲突并且被跳过。叹
4c74356b41 '19

18

这是我的解决方案

简单尝试:

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;
}

9

也许这不是确切的情况,但对于使用和运行项目的docker容器的任何人,在我的情况下,我拥有所需的一切:reactreact-routerwebpack-dev-servernginx.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;"]

1
你救了我的一天!
Bilal Hussain


0

对我来说,直到我添加了根指令,任何事情都没有起作用。对于我来说,这也可以使用反向代理来建立/ api /网络服务器端点。

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

0

我当时正在处理同样的问题,我认为那是一个conf错误,但没有。我正在将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

希望能帮助到你。


0
location / {
    root /path/to/root/directory/of/staticfiles;
    index index.html;
    try_files $uri /index.html;
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.