首页 文章

使用React Router重新加载页面会出现404错误

提问于
浏览
3

我有...

后端

Node.js / express服务器,在向某些路由发出请求时提供文件 .

前端

响应调用后端请求数据填充页面的页面 .

我在前端使用react-router v4 . 每当我导航到不在确切路径上的路线并重新加载页面时,我都会收到404错误 . 我理解为什么这不起作用;浏览器向react-router处理的路径发出请求,由于它在服务器上找不到该路由,我得到404 .

我正在寻求解决这个问题的方法 .

// BrowserRouter imported as Router
<Router>
   <Route exact path='/main' component={Main} />
   <Route path='/sub1' component={SubOne} />
   <Route path='/sub2' component={SubTwo} />
</Router>

当我在浏览器中转到 /main 时,将呈现 <Main /> . 假设在 <Main /> 内,分别有 /sub1/sub2 的链接 . 我点击 /sub2 . 组件和页面内容的呈现不会失败 . 然后我意外地或有意地刷新页面(比如组件Sub2将状态提升到Main) .

刷新后如何避免获得404?如果我使用React-Router,如何在刷新后呈现“我”的页面/组件?

4 回答

  • 1

    你得到404的原因是刷新页面构成网络往返点击 server ,而react-router是一个 client-side 路由库,它不处理服务器端路由 .

    当用户点击刷新按钮或直接访问登陆页面以外的页面时,例如, / help或/ help / online作为Web服务器绕过索引文件以在此位置定位文件 . 由于您的应用程序是SPA,因此Web服务器将无法尝试检索文件并向用户返回404 - Not Found消息 .

    由于您使用的是Express服务器,因此可以使用connect-history-api-fallback(Express中间件)通过索引页面代理所有收到的请求(包括未知的请求/ / sub2) . 然后重新启动SPA并通过react路由器路由到客户端上的/ sub2 .

    如果您使用webpack-dev-server进行本地开发,那么就像打开devServer.historyApiFallback一样简单 .

  • 0

    使用“重定向”指令将子路径映射到实际路径

    https://reacttraining.com/react-router/web/example/no-match

  • 0

    我在2个月前遇到了同样的问题 . 我对使用React的服务器端渲染知之甚少 . 我对它的一般概念感到困惑 . 但是,我不想使用create-react-app cli . 我想用自己的样板 . 在做研究时,我发现我必须配置我的webpack来处理我的404重新加载后备 .

    这是我目前的webpack设置:

    请注意,只需注意 historyApiFallback: true ,如果您使用的是v4,则可以刷新页面而不会抛出404错误 . 另外,我忘了提到这需要webpack-dev-server才能工作 .

    const webpack = require('webpack');
    const path = require('path');
    const nodeExternals = require('webpack-node-externals');
    const HtmlWebPackPlugin = require('html-webpack-plugin');
    
    var browserConfig = {
        devServer: {
            historyApiFallback: true,
            proxy: {
                "/api": "http://localhost:3012"
            }
        },
        entry: ['babel-polyfill', __dirname + '/src/index.js'],
        output: {
            path: path.resolve(__dirname + '/public'),
            filename: 'bundle.js',
            publicPath: '/'
        },
        module: {
            rules: [
                {
                    test: /\.jsx?$/,
                    exclude: /node_modules/,
                    use: {
                        loader: 'babel-loader',
                        query: {
                            presets: ['react', 'env', 'stage-0']
                        }
                    }
                }
            ]
        },
        plugins: [
            new HtmlWebPackPlugin({
                template: './public/index.html',
            })
        ]
    }
    
    var serverConfig = {
        target: 'node',
        externals: [nodeExternals()],
        entry: __dirname + '/server/main.js',
        output: {
            path: path.resolve(__dirname + '/public'),
            filename: 'server.js',
            publicPath: '/'
        },
        module: {
            rules: [
                {
                    test: /\.js$/,
                    exclude: /node_modules/,
                    use: {
                        loader: 'babel-loader',
                        query: {
                            presets: ['react', 'env', 'stage-0']
                        }
                    }
                }
            ]
        }
    }
    
    module.exports = [browserConfig, serverConfig]
    
  • 0

    我的解决方案是使用content-history-api-fallback模块

    第一:从'connect-history-api-fallback'导入历史记录

    然后:

    app.use(history({
        rewrites:[
            {from: /^\/api\/.*$/, to: function(context){
                return context.parsedUrl.pathname;
            }},
            {from: /\/.*/, to: '/'}
        ]
    }))
    
    app.get('/', function(req, res, next){
        res.render('index');
    })
    
    app.use('/api', api);
    

相关问题