React应用在生产环境下刷新页面会出现404错误,但在开发环境中不会出现。

4
我有一个React应用程序,在导航中遇到了404问题,如果我尝试刷新不是根页面的页面,它会给我404错误。
问题是只发生在生产环境中,而不是开发环境中。 在开发环境中,我使用npm start,在生产环境中,我使用serve build。
这使得调试更加复杂,因为我失去了用于调试的热重载选项。每次更改后我必须编译我的Docker映像。
以下是我的部分代码:
<BrowserRouter>
        <div>

            <Switch>
                <Route exact path="/premiere-connexion" component={FirstLoginLayout}/>
                {(user.state === "1" && window.location.pathname === "/premiere-connexion") &&
                <Redirect to="/premiere-connexion"/>}
                <PrivateRoute path="/bo" component={BackOfficeLayout} profiles={["ADMIN"]}/>
                <Route exact path="/" component={Customer}/>
                <Redirect to="/"/>
            </Switch>
            }
        </div>
    </BrowserRouter>

有任何想法应该如何在本地复制它?


你使用过路由器吗? - iamrajshah
你的应用程序是否位于网页的子目录中(https://example.com/subdirectory)? - Rallen
@Rallen 不是,我使用子域名和Caddy - Juliatzin
1
如果您正在使用Zeit的serve来提供构建文件夹,则可能需要告诉它将所有请求重定向到index.html文件,否则,serve将期望您的深度链接是构建文件夹中的文件夹。请查看serve文档中的配置部分。有一个rewrite选项可能会有用。 - hbentlov
@hbentlov 我不确定应该把serve.json文件放在哪个文件夹里?我是用 npm run build 命令构建这个项目的。 - Juliatzin
显示剩余5条评论
3个回答

4

根据@hbentlov的建议,我解决了这个问题,创建了一个文件serve.jsonpublic/文件夹中,内容如下:

最初的回答:

{
  "rewrites": [{
    "source": "**",
    "destination": "/index.html"
  }]
}

0
如果使用Netlify托管,则可以尝试创建文件“_redirects”并添加1行代码:

/* /index.html 200

欢迎来到StackOverFlow。这个回答并不是原问题的合适答案。请考虑将其删除,否则可能会被踩。 - vmf91

0

我也因为同样的问题来到了这里;当你直接调用React Router地址时,在Docker上运行react会出现404错误。

解决方案是告诉nginx将不存在的url发送到index.html(这非常简单)

你需要创建一个nginx.conf文件(在我的情况下是与Dockerfile放在一起),并将其复制到容器内的 /etc/nginx/nginx.conf目录中。

这是nginx.conf内容:

# auto detects a good number of processes to run
worker_processes auto;

#Provides the configuration file context in which the directives that affect connection processing are specified.
events {
    # Sets the maximum number of simultaneous connections that can be opened by a worker process.
    worker_connections 8000;
    # Tells the worker to accept multiple connections at a time
    multi_accept on;
}


http {
    # what times to include
    include       /etc/nginx/mime.types;
    # what is the default one
    default_type  application/octet-stream;

    # Sets the path, format, and configuration for a buffered log write
    log_format compression '$remote_addr - $remote_user [$time_local] '
        '"$request" $status $upstream_addr '
        '"$http_referer" "$http_user_agent"';

    server {
        # listen on port 80
        listen 80;
        # save logs here
        access_log /var/log/nginx/access.log compression;

        # where the root here
        root /usr/share/nginx/html;
        # what file to server as index
        index index.html index.htm;

        location / {
            # First attempt to serve request as file, then
            # as directory, then fall back to redirecting to index.html
            try_files $uri $uri/ /index.html;
        }

        # Media: images, icons, video, audio, HTC
        location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
          expires 1M;
          access_log off;
          add_header Cache-Control "public";
        }

        # Javascript and CSS files
        location ~* \.(?:css|js)$ {
            try_files $uri =404;
            expires 1y;
            access_log off;
            add_header Cache-Control "public";
        }

        # Any route containing a file extension (e.g. /devicesfile.js)
        location ~ ^.+\..+$ {
            try_files $uri =404;
        }
    }
}

这是如何应用它的方法:在Dockerfile中添加“COPY nginx.conf /etc/nginx/nginx.conf”。 我的Dockerfile看起来像这样:
# build environment
FROM node:13.12.0-alpine as build
WORKDIR /app
ENV PATH /app/node_modules/.bin:$PATH
COPY package.json ./
COPY package-lock.json ./
RUN npm ci --silent
RUN npm install react-scripts@3.4.1 -g --silent
COPY . ./
RUN npm run build


# production environment
FROM nginx:stable-alpine
# Nginx configuration
COPY nginx.conf /etc/nginx/nginx.conf

COPY --from=build /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

这行代码 try_files $uri $uri/ /index.html; 告诉 nginx 回退到 index.html

希望能帮助其他人


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接