【问题标题】:nginx + react static build path can't be accessed on direct url hit直接 url 命中时无法访问 nginx + react 静态构建路径
【发布时间】:2021-07-12 07:54:18
【问题描述】:

我正在尝试使用 nginx 部署我的 create-react-app 的静态构建。我已经添加了homepage: ".",这是必需的。

而且最后的输出还是很不错的,只是我不能直接访问一些网址。

我正在使用 react-router-dom 和 react-admin:

index.js:

<BrowserRouter>
        <Switch>
            <Route exact path="/">
                <Redirect to="/home"/>
            </Route>
            <Route path="/login" component={LoginComponent}/>
            <Route path="/home" component={HomeComponent}/>
            <Route path="*">
                <Redirect to={"/login"}/>
            </Route>
        </Switch>
    </BrowserRouter>

HomeComponent里面有react-admin,也很简单:

<Admin
                    dataProvider={myDataProvider}
                    authProvider={myAuthProvider(this.props)}
                    layout={MyLayout}>
                    <Resource title="Users" name="users" list={UserList}/>
                    <Resource title="Transactions" name="transactions" list={TransactionList}/>
                </Admin>

但是当我尝试直接点击该 URL 时:

我的nginx.conf 文件很简单:

root@ubuntu-s-1vcpu-1gb-blr1-01:/etc/nginx# cat nginx.conf 
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
    worker_connections 768;
    # multi_accept on;
}

http {

    ##
    # Basic Settings
    ##

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    # server_tokens off;

    # server_names_hash_bucket_size 64;
    # server_name_in_redirect off;

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

    ##
    # SSL Settings
    ##

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
    ssl_prefer_server_ciphers on;

    ##
    # Logging Settings
    ##

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    ##
    # Gzip Settings
    ##

    gzip on;

    # gzip_vary on;
    # gzip_proxied any;
    # gzip_comp_level 6;
    # gzip_buffers 16 8k;
    # gzip_http_version 1.1;
    # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

    ##
    # Virtual Host Configs
    ##

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}

location / {
    error_page 404 =200 /index.html;
}

【问题讨论】:

    标签: reactjs nginx react-router-dom react-admin


    【解决方案1】:

    出现此错误是因为 nginx 无法匹配提供的路径 home#/transactions 上的文件。

    由于您尚未提供您的nginx.conf 文件。我的假设是您缺少 try_files 指令或整个指令中的后备。

    正如您提到的,您使用的是create-react-app,这意味着您的构建输出是一个index.html 文件和一堆静态资产。

    如果找到静态资产,则以下规则应匹配它,如果它不存在则回退到 index.html,您的前端路由器将从那里处理其余部分并向您显示正确的页面。

    try_files $uri $uri/ /index.html;
    

    更新(OP 添加了 nginx.conf):

    提供的nginx.conf 文件的location 块无效。 location 应在 server 块下指定。

    我注意到在您的nginx.conf 文件中,您正在导入多个其他配置文件,并且添加这些配置文件会很有用,因为它们可能会对结果产生影响。这个导入特别引起了我的注意:

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

    这条路径可以匹配default.conf(如果存在),但我现在只是猜测。如果确实如此并且default.conf 没有改变,那将解释您所描述的行为,因为default.conf 看起来像这样:

    server {
       listen       80;
       server_name  localhost;
    
       #charset koi8-r;
       #access_log  /var/log/nginx/log/host.access.log  main;
    
       location / {
           root   /usr/share/nginx/html;
           index  index.html index.htm;
       }
    
       #error_page  404              /404.html;
    
       # redirect server error pages to the static page /50x.html
       #
       error_page   500 502 503 504  /50x.html;
       location = /50x.html {
           root   /usr/share/nginx/html;
       }
    
       # proxy the PHP scripts to Apache listening on 127.0.0.1:80
       #
       #location ~ \.php$ {
       #    proxy_pass   http://127.0.0.1;
       #}
    
       # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
       #
       #location ~ \.php$ {
       #    root           html;
       #    fastcgi_pass   127.0.0.1:9000;
       #    fastcgi_index  index.php;
       #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
       #    include        fastcgi_params;
       #}
    
       # deny access to .htaccess files, if Apache's document root
       # concurs with nginx's one
       #
       #location ~ /\.ht {
       #    deny  all;
       #}
    }
    

    有几种可能的解决方案(假设default.conf 导致问题):

    1. try_files 添加到默认配置中,如下所示:
    # default.conf
    
    server {
       ...
       location / {
           root   /usr/share/nginx/html;
           try_files $uri $uri/ /index.html;
           index  index.html index.htm;
       }
    }
    

    如果default.conf 与其他配置共享,这对他们来说是破坏

    1. (首选) 省略default.conf 的导入,将自定义服务器添加到nginx.conf。像这样简单的服务器就可以解决问题:
    http {
        ...
        server {
            listen       80; # port
            server_name  _; # name
            root   /usr/share/nginx/html; # build dir
            try_files $uri $uri/ /index.html;
            index  index.html;
        }
    }
    

    【讨论】:

    • 我的错,我已经添加了我的conf文件,实际上我在conf文件中添加了404重定向规则,你能再检查一下吗?
    • 感谢您提供更多信息!我已更新我的答案以响应添加 nginx.conf 文件。
    • 不幸的是,如果直接访问它,添加 404 重定向会使您丢失当前的 url,因为它总是会将您重定向到根目录。可能存在这不是适当行为的用例。您在示例中尝试执行的操作并不是真正的 404 重定向,更像是自定义 404 页面,即索引,nginx 在其中返回 OK 响应。这对我来说似乎有点 hacky 和不必要的,因为 try_files 已经实现了所有需要的逻辑。
    猜你喜欢
    • 2018-03-01
    • 2022-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-31
    • 1970-01-01
    • 2021-12-28
    相关资源
    最近更新 更多