首页 文章

手动刷新或写入时,React-router URL不起作用

提问于
浏览
376

我正在使用React-router,当我点击链接按钮时它工作正常,但是当我刷新我的网页时它没有加载我想要的东西 .

例如,我进入localhost / joblist,一切都很好,因为我来到这里按一个链接 . 但是,如果我刷新网页,我得到:不能GET / joblist

默认情况下它不像这样工作 . 最初我有我的URL:localhost /#/和localhost /#/ joblist,他们工作得非常好 . 但我不喜欢这种网址,所以试图抹去我写的'#':

Router.run(routes, Router.HistoryLocation, function (Handler) {
 React.render(<Handler/>, document.body);
});

localhost /不会发生这个问题,这个问题总是返回我想要的 .

编辑:这个应用程序是单页面,因此/ joblist不需要向任何服务器询问任何内容 .

EDIT2:我的整个路由器 .

var routes = (
    <Route name="app" path="/" handler={App}>
        <Route name="joblist" path="/joblist" handler={JobList}/>
        <DefaultRoute handler={Dashboard}/>
        <NotFoundRoute handler={NotFound}/>
    </Route>
);

Router.run(routes, Router.HistoryLocation, function (Handler) {
  React.render(<Handler/>, document.body);
});

30 回答

  • 73

    这里的答案都非常有用,对我来说有用的是配置我的Webpack服务器以期望路由 .

    devServer: {
        historyApiFallback: true,
        contentBase: './',
        hot: true
      },
    

    historyApiFallback是我解决这个问题的原因 . 现在路由工作正常,我可以刷新页面或直接输入URL . 无需担心节点服务器上的解决方法 . 这个答案显然只有在你使用webpack时才有效 .

    编辑:请在此处查看我的答案,了解为何需要更详细的原因:https://stackoverflow.com/a/37622953/5217568

  • 0

    实际解决方法:

    • 将原始html文件复制并重命名为joblist.html

    • 使用joblist.html作为路径路径

    无需服务器端更改 .

  • 2

    我使用create-react-app来制作一个网站,并且在这里提出了相同的问题 . 我使用 react-router-dom 包中的 BrowserRouting . 我在Nginx服务器上运行,为我解决了这个问题,将以下内容添加到 /etc/nginx/yourconfig.conf

    location / {
      if (!-e $request_filename){
        rewrite ^(.*)$ /index.html break;
      }
    }
    

    这对应于在运行Appache时将以下内容添加到 .htaccess

    Options -MultiViews
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.html [QSA,L]
    

    这似乎也是Facebook自己提出的解决方案,可以找到here

  • 0

    In case, anyone is here looking for solution on React JS SPA with Laravel. 接受的答案是对这些问题发生原因的最佳解释 . 如前所述,您必须配置客户端和服务器端 . 在您的刀片模板中,包含js捆绑文件,请确保使用 URL facade 这样

    <script src="{{ URL::to('js/user/spa.js') }}"></script>
    

    在您的路由中,请确保将其添加到刀片模板所在的主 endpoints . 例如,

    Route::get('/setting-alerts', function () {
       return view('user.set-alerts');
    });
    

    以上是刀片模板的主要 endpoints . 现在添加一个可选路线,

    Route::get('/setting-alerts/{spa?}', function () {
      return view('user.set-alerts');
    });
    

    发生的问题是首先加载刀片模板,然后加载反应路由器 . 因此,当您加载 '/setting-alerts' 时,它会加载html和js . 但是当你加载 '/setting-alerts/about' 时,它首先在服务器端加载 . 由于在服务器端,此位置没有任何内容,因此返回未找到 . 当你有这个可选的路由器时,它会加载同一个页面并且反应路由器也被加载,然后反应加载器决定显示哪个组件 . 希望这可以帮助 .

  • 0

    使用preact-router进行Preact的解决方案

    Works with refresh and direct access

    对于那些通过谷歌发现这一点的人来说,这是一个preact-router哈希历史的演示:

    const { h, Component, render } = preact; /** @jsx h */
    const { Router } = preactRouter;
    const { createHashHistory } = History;
    const App = () => (
        <div>
            <AddressBar />
    
            <Router history={createHashHistory()}>
                <div path="/">
                    <p>
                        all paths in preact-router are still /normal/urls.
                        using hash history rewrites them to /#/hash/urls
                    </p>
                    Example: <a href="/page2">page 2</a>
                </div>
                <div path="/page2">
                    <p>Page Two</p>
                    <a href="/">back to home</a>
    </div> </Router> </div> );

    https://jsfiddle.net/developit/gLyL6rbn/

  • 9

    If you are using Create React App:

    对于许多主要托管平台的解决方案,您可以在Create React App页面上找到HERE,这是一个很好的步骤 . 例如,我使用React Router v4和Netlify作为我的前端代码 . 所需要的只是将1个文件添加到我的公共文件夹("_redirects")和该文件中的一行代码:

    /*  /index.html  200
    

    现在我的网站在进入浏览器或者某人点击刷新时正确呈现了像mysite.com/pricing这样的路径 .

  • 5

    如果确实有index.html的回退,请确保在index.html文件中有以下内容:

    <script>
      System.config({ baseURL: '/' });
    </script>
    

    这可能因项目而异 .

  • 0

    如果您在IIS中托管;将此添加到我的webconfig解决了我的问题

    <httpErrors errorMode="Custom" defaultResponseMode="ExecuteURL">
            <remove statusCode="500" subStatusCode="100" />
            <remove statusCode="500" subStatusCode="-1" />
            <remove statusCode="404" subStatusCode="-1" />
            <error statusCode="404" path="/" responseMode="ExecuteURL" />
            <error statusCode="500" prefixLanguageFilePath="" path="/error_500.asp" responseMode="ExecuteURL" />
            <error statusCode="500" subStatusCode="100" path="/error_500.asp" responseMode="ExecuteURL" />
        </httpErrors>
    

    您可以为任何其他服务器进行类似配置

  • 2

    我有同样的问题和this解决方案为我们工作..

    背景:

    我们在同一台服务器上托管多个应用 . 当我们刷新服务器时,不会理解在该特定应用程序的dist文件夹中查找索引的位置 . 上面的链接将带您了解对我们有用的东西......希望这会有所帮助,因为我们花了相当长的时间来找出满足我们需求的解决方案 .

    我们正在使用:

    package.json
    
    "dependencies": {
    "babel-polyfill": "^6.23.0",
    "ejs": "^2.5.6",
    "express": "^4.15.2",
    "prop-types": "^15.5.6",
    "react": "^15.5.4",
    "react-dom": "^15.5.4",
    "react-redux": "^5.0.4",
    "react-router": "^3.0.2",
    "react-router-redux": "^4.0.8",
    "redux": "^3.6.0",
    "redux-persist": "^4.6.0",
    "redux-thunk": "^2.2.0",
    "webpack": "^2.4.1"
    }
    

    我的webpack.config.js

    webpack.config.js
    
    /* eslint-disable */
    const path = require('path');
    const webpack = require('webpack');
    const HtmlWebpackPlugin = require('html-webpack-plugin');
    const babelPolyfill = require('babel-polyfill');
    const HTMLWebpackPluginConfig = new HtmlWebpackPlugin({
      template: __dirname + '/app/views/index.html',
      filename: 'index.html',
      inject: 'body'
    });
    
    module.exports = {
      entry: [
        'babel-polyfill', './app/index.js'
      ],
      output: {
        path: __dirname + '/dist/your_app_name_here',
        filename: 'index_bundle.js'
      },
      module: {
        rules: [{
          test: /\.js$/,
          loader: 'babel-loader',
          query : {
              presets : ["env", "react", "stage-1"]
          },
          exclude: /node_modules/
        }]
      },
      plugins: [HTMLWebpackPluginConfig]
    }
    

    我的index.js

    index.js
    
    import React from 'react'
    import ReactDOM from 'react-dom'
    import Routes from './Routes'
    import { Provider } from 'react-redux'
    import { createHistory } from 'history'
    import { useRouterHistory } from 'react-router'
    import configureStore from './store/configureStore'
    import { syncHistoryWithStore } from 'react-router-redux'
    import { persistStore } from 'redux-persist'
    
    const store = configureStore();
    
    const browserHistory = useRouterHistory(createHistory) ({
      basename: '/your_app_name_here'
    })
    const history = syncHistoryWithStore(browserHistory, store)
    
    persistStore(store, {blacklist: ['routing']}, () => {
      console.log('rehydration complete')
    })
    // persistStore(store).purge()
    
    
    ReactDOM.render(
        <Provider store={store}>
          <div>
            <Routes history={history} />
          </div>
        </Provider>,
      document.getElementById('mount')
    )
    

    我的app.js

    var express = require('express');
    var app = express();
    
    app.use(express.static(__dirname + '/dist'));
    // app.use(express.static(__dirname + '/app/assets'));
    app.set('views', __dirname + '/dist/your_app_name_here');
    app.engine('html', require('ejs').renderFile);
    app.set('view engine', 'html');
    
    app.get('/*', function (req, res) {
        res.render('index');
    });
    
    app.listen(8081, function () {
      console.log('MD listening on port 8081!');
    });
    
  • 2

    Production stack: React, React Router v4, BrowswerRouter, Express, Nginx

    1)用户浏览器路由器的漂亮网址

    // app.js
    
    import { BrowserRouter as Router } from 'react-router-dom'
    
    const App = () {
      render() {
        return (
            <Router>
               // your routes here
            </Router>
        )
      }
    }
    

    2)使用 /* 将index.html添加到所有未知请求

    // server.js
    
    app.get('/*', function(req, res) {   
      res.sendFile(path.join(__dirname, 'path/to/your/index.html'), function(err) {
        if (err) {
          res.status(500).send(err)
        }
      })
    })
    

    3)用 webpack -p 捆绑webpack

    4)运行 nodemon server.jsnode server.js

    编辑:你可能想让nginx在服务器块中处理这个并忽略第2步:

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

    将此添加到webpack.congif.js

    devServer: {
          historyApiFallback: true
      }
    
  • 652

    这可以解决您的问题

    我在 生产环境 模式下的ReactJS应用程序中也遇到了同样的问题 . 这是问题的解决方案 .

    1.将路由历史记录更改为“hashHistory”而不是browserHistory

    <Router history={hashHistory} >
       <Route path="/home" component={Home} />
       <Route path="/aboutus" component={AboutUs} />
     </Router>
    

    现在使用该命令构建应用程序

    sudo npm run build
    

    然后放置在var / www /文件夹中构建文件夹,现在应用程序正常工作,在每个URL中添加了#tag . 喜欢

    localhost /#/ home localhost /#/ aboutus

    解决方案2:没有使用browserHistory的#tag,

    在您的路由器中设置您的history = ,现在使用sudo npm run build构建它 .

    您需要创建“conf”文件来解决404未找到的页面,conf文件应该是这样的 .

    打开你的终端输入以下命令

    cd / etc / apache2 / sites-available ls nano sample.conf在其中添加以下内容 .

    <VirtualHost *:80>
        ServerAdmin admin@0.0.0.0
        ServerName 0.0.0.0
        ServerAlias 0.0.0.0
        DocumentRoot /var/www/html/
    
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
        <Directory "/var/www/html/">
                Options Indexes FollowSymLinks
                AllowOverride all
                Require all granted
        </Directory>
    </VirtualHost>
    

    现在,您需要使用以下命令启用sample.conf文件

    cd /etc/apache2/sites-available
    sudo a2ensite sample.conf
    

    然后它会要求你重新加载apache服务器,使用sudo service apache2 reload或restart

    然后打开localhost / build文件夹并添加包含以下内容的.htaccess文件 .

    RewriteEngine On
       RewriteBase /
       RewriteCond %{REQUEST_FILENAME} !-f
       RewriteCond %{REQUEST_FILENAME} !-d
       RewriteCond %{REQUEST_FILENAME} !-l
       RewriteRule ^.*$ / [L,QSA]
    

    现在该应用程序正常工作 .

    注意:将0.0.0.0 ip更改为本地IP地址 .

    如果对此有任何疑问,请随时提出评论 .

    我希望它对其他人有所帮助 .

  • 0

    如果您在后端使用Express或其他框架,您可以添加如下的类似配置并查看配置中的Webpack公共路径,如果您使用的是BrowserRouter,即使重新加载也应该可以正常工作

    ` expressApp.get('/*', (request, response) => {
        response.sendFile(path.join(__dirname, '../public/index.html'));
      });`
    
  • 36

    我喜欢这种处理方式 . 尝试在服务器端添加: yourSPAPageRoute/* 以解决此问题 .

    我采用这种方法,因为即使是原生的HTML5 History API也不支持页面刷新时的正确重定向(据我所知) .

    注意:选定的答案已经解决了这个问题,但我想更具体一点 .

    Express Route

    经过测试,只是想分享一下 .

    希望能帮助到你 .

  • 0

    我还没有使用服务器端渲染,但是我遇到了与OP相同的问题,其中Link似乎大部分时间工作正常,但是当我有一个参数时失败了 . 我会在这里记录我的解决方案,看看它是否有助于任何人 .

    我的主要jsx包含这个:

    <Route onEnter={requireLogin} path="detail/:id" component={ModelDetail} />
    

    这适用于第一个匹配的链接,但是当嵌套在该模型的详细信息页面上的 <Link> 表达式中的:id更改时,URL会在浏览器栏中更改,但页面内容最初不会更改以反映链接的模型 .

    问题是我使用 props.params.idcomponentDidMount 中设置了模型 . 组件刚刚安装一次,这意味着第一个模型是粘在页面上的模型,随后的链接会更改道具,但保持页面不变 .

    componentDidMountcomponentWillReceiveProps (它基于下一个道具)中的组件状态中设置模型可以解决问题,并且页面内容会发生变化以反映所需的模型 .

  • 31

    如果您在IIS上托管您的react应用程序,只需添加一个包含以下内容的web.config文件:

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <system.webServer>
        <httpErrors errorMode="Custom" existingResponse="Replace">
            <remove statusCode="404" subStatusCode="-1" />
            <error statusCode="404" path="/" responseMode="ExecuteURL" />
        </httpErrors>
      </system.webServer>
    </configuration>
    

    这将告诉IIS服务器将主页面返回到客户端而不是404错误,并且不需要使用哈希历史记录 .

  • 0

    对于那些使用IIS 10的人来说,这就是你应该做的事情 . 请确保您使用的是browserHistory . 至于参考,我将给出路由的代码,但这不重要,重要的是下面的组件代码之后的下一步:

    class App extends Component {
        render() {
            return (
                <Router history={browserHistory}>
                    <div>
                        <Root>
                            <Switch>
                                <Route exact path={"/"} component={Home} />    
                                <Route path={"/home"} component={Home} />
                                <Route path={"/createnewproject"} component={CreateNewProject} />
                                <Route path={"/projects"} component={Projects} />
                                <Route path="*" component={NotFoundRoute} />
                            </Switch>
                        </Root>
                    </div>
                </Router>
            )
        }
    }
    render (<App />, window.document.getElementById("app"));
    

    由于问题是IIS从客户端浏览器接收请求,它会将URL解释为要求页面,然后返回404页面,因为没有可用页面 . 请执行下列操作:

    • 打开IIS

    • 展开服务器,然后打开“站点文件夹”

    • 单击网站/应用程序

    • 转到错误页面

    • 打开列表中的404错误状态项

    • 而不是选项"Insert content from static file into the error response",将其更改为"Execute a URL on this site"并将"/"斜杠值添加到URL .

    它现在可以正常工作了 .

    我希望它有所帮助 . :-)

  • 0

    这个主题有点陈旧和解决但我想建议你一个简单,明确和更好的解决方案 . 如果您使用Web服务器,它可以工作 .

    在http 404的情况下,每个Web服务器都能够将用户重定向到错误页面 . 要解决此问题,您需要将用户重定向到索引页面 .

    如果您使用Java基本服务器(tomcat或任何Java应用程序服务器),解决方案可能如下:

    web.xml:

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
             version="3.1">
    
        <!-- WELCOME FILE LIST -->
        <welcome-file-list>
            <welcome-file>index.jsp</welcome-file>
        </welcome-file-list>
    
        <!-- ERROR PAGES DEFINITION -->
        <error-page>
            <error-code>404</error-code>
            <location>/index.jsp</location>
        </error-page>
    
    </web-app>
    

    例:

    • GET http://example.com/about

    • Web服务器抛出http 404,因为服务器端不存在此页面

    • 错误页面配置告诉服务器将index.jsp页面发送回用户

    • 然后JS将在客户端执行剩余的工作,因为客户端的URL仍然是http://example.com/about .

    就是这样,没有更多魔法需要:)

  • 6

    尝试使用以下代码在公用文件夹中添加“.htaccess”文件 .

    RewriteEngine On
    RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
    RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
    RewriteRule ^ - [L]
    
    RewriteRule ^ /index.html [L]
    
  • 4

    如果你正在使用firebase,你所要做的就是确保你的应用程序根目录中的firebase.json文件中有一个重写属性(在托管部分) .

    例如:

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

    希望这可以为其他人节省挫折和浪费时间 .

    快乐的编码......

    进一步阅读该主题:

    https://firebase.google.com/docs/hosting/full-config#rewrites

    Firebase CLI: "Configure as a single-page app (rewrite all urls to /index.html)"

  • -9

    If you're hosting a react app via AWS Static S3 Hosting & CloudFront

    这个问题由CloudFront以403 Access Denied消息响应,因为它预期/某些/其他/路径存在于我的S3文件夹中,但该路径仅存在于React与react-router的路由中 .

    解决方案是设置分发错误页面规则 . 转到CloudFront设置并选择您的分发 . 接下来转到“错误页面”选项卡 . 单击“创建自定义错误响应”并为403添加条目,因为这是我们获得的错误状态代码 . 将响应页面路径设置为/index.html,将状态代码设置为200.最终结果令我惊讶于它的简单性 . 提供了索引页面,但URL保留在浏览器中,因此一旦反应应用程序加载,它将检测URL路径并导航到所需的路径 .

    Error Pages 403 Rule

  • 9

    这里有很多好的答案,不需要在这里写出更多的答案 .

    但是,我在这里提供另一个好的链接

    https://css-tricks.com/learning-react-router/#article-header-id-9

  • 7

    可以通过两种不同的方式调用路由器,具体取决于导航是在客户端还是在服务器上进行 . 您已将其配置为客户端操作 . 关键参数是run method的第二个位置 .

    当您使用React Router Link组件时,它会阻止浏览器导航并调用transitionTo来执行客户端导航 . 您正在使用HistoryLocation,因此它使用HTML5历史记录API通过模拟地址栏中的新URL来完成导航错觉 . 如果您使用的是较旧的浏览器,则无法使用 . 您需要使用HashLocation组件 .

    当您点击刷新时,您将绕过所有React和React路由器代码 . 服务器获取 /joblist 的请求,它必须返回一些东西 . 在服务器上,您需要将请求的路径传递给 run 方法,以便呈现正确的视图 . 您可以使用相同的路线图,但您可能需要对 Router.run 进行不同的调用 . 正如Charles指出的那样,您可以使用URL重写来处理这个问题 . 另一种选择是使用node.js服务器来处理所有请求,并将路径值作为location参数传递 .

    例如,在express中,它可能如下所示:

    var app = express();
    
    app.get('*', function (req, res) { // This wildcard method handles all requests
    
        Router.run(routes, req.path, function (Handler, state) {
            var element = React.createElement(Handler);
            var html = React.renderToString(element);
            res.render('main', { content: html });
        });
    });
    

    请注意,请求路径正在传递给 run . 要做到这一点,您需要有一个服务器端视图引擎,您可以将呈现的HTML传递给 . 使用 renderToString 以及在服务器上运行React时还有许多其他注意事项 . 在服务器上呈现页面后,当您的应用程序加载到客户端时,它将再次呈现,根据需要更新服务器端呈现的HTML .

  • 1

    你可以改变你的htaccess并插入:

    RewriteBase /
    RewriteRule ^index\.html$ - [L]
     RewriteCond %{REQUEST_FILENAME} !-f
     RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.html [L]
    

    我正在使用 react: "^15.3.2"react-router: "^3.0.0"history: "^4.3.0"

  • 0

    在index.html head 中,添加以下内容:

    <base href="/">
    <!-- This must come before the css and javascripts -->
    

    然后在使用webpack dev server运行时使用此命令 .

    webpack-dev-server --mode development --hot --inline --content-base=dist --history-api-fallback
    

    --history-api-fallback 是重要的部分

  • 0

    对于 React Router V4 用户:

    如果您尝试通过其他答案中提到的哈希历史技术解决此问题,请注意

    <Router history={hashHistory} >

    在V4中不起作用,请改用 HashRouter

    import { HashRouter } from 'react-router-dom'
    
    <HashRouter>
      <App/>
    </HashRouter>
    

    参考:https://reacttraining.com/react-router/web/api/HashRouter

  • 25

    看看对已接受答案的评论和这个问题的一般性质(“不工作”),我认为这可能是对这里涉及的问题进行一些一般性解释的好地方 . 因此,这个答案旨在作为OP的具体用例的背景信息/详细说明 . 请多多包涵 .

    服务器端与客户端

    要理解这一点的第一件大事是,现在有2个地方解释了URL,而在'the old days'中只有1个 . 在过去,当生活很简单时,一些用户向服务器发送了 http://example.com/about 的请求,该服务器检查了URL的路径部分,确定用户正在请求about页面然后发回该页面 .

    使用React-Router提供的客户端路由,事情就不那么简单了 . 起初,客户端尚未加载任何JS代码 . 所以第一个请求将永远是服务器 . 然后,它将返回一个页面,其中包含所需的脚本标记以加载React和React Router等 . 只有当这些脚本加载时才会启动第2阶段 . 在阶段2中,例如,当用户单击'About us'导航链接时,URL仅在本地更改为 http://example.com/about (由History API实现),但是 no request to the server is made . 相反,React Router已经完成了's thing on the client side, determines which React view to render and renders it. Assuming your about page does not need to make any REST calls, it' . 您已经从Home转换为About Us而没有任何服务器请求被解雇 .

    因此,基本上当您单击链接时,会运行一些Javascript来操作地址栏中的URL,而不会导致页面刷新,从而导致React Router执行页面转换 on the client side .

    但现在考虑如果您将URL复制粘贴到地址栏并通过电子邮件发送给朋友,会发生什么 . 您的朋友尚未加载您的网站 . 换句话说,她仍处于第1阶段 . 尚未在她的机器上运行React Router . 所以她的浏览器会将 server request 设为 http://example.com/about .

    这就是你的麻烦所在开始 . 到目前为止,只需在服务器的webroot上放置一个静态HTML即可 . 但是,当从服务器请求时,这将为所有其他URL提供 404 错误 . 这些相同的URL在客户端工作正常,因为React Router正在为您执行路由,但它们在服务器端失败,除非您让服务器理解它们 .

    结合服务器端和客户端路由

    如果您希望 http://example.com/about URL在服务器端和客户端都可以工作,则需要在服务器端和客户端为它设置路由 . 有道理吗?

    这就是你的选择开始的地方 . 解决方案包括完全绕过问题,通过返回引导HTML的全能路由,以及服务器和客户端运行相同JS代码的全面同构方法 .

    .

    完全绕过问题:哈希历史

    使用Hash History而不是Browser History,about页面的URL将如下所示: http://example.com/#/about 散列( # )符号后面的部分未发送到服务器 . 因此服务器只能看到 http://example.com/ 并按预期发送索引页面 . React-Router将获取 #/about 部分并显示正确的页面 .

    Downsides

    • 'ugly'个网址

    • 使用此方法无法进行服务器端呈现 . 就搜索引擎优化(SEO)而言,您的网站由一个页面组成,几乎没有任何内容 .

    .

    Catch-all

    使用这种方法,您可以使用浏览器历史记录,但只需在服务器上设置一个catch-all,将 /* 发送到 index.html ,从而有效地为您提供与哈希历史记录相同的情况 . 但是,您确实拥有干净的URL,您可以在以后改进此方案,而不必使用户的所有收藏夹无效 .

    Downsides

    • 设置起来比较复杂

    • 仍然没有好的SEO

    .

    混合动力车

    在混合方法中,您可以通过为特定路由添加特定脚本来扩展catch-all场景 . 您可以制作一些简单的PHP脚本来返回包含内容的网站中最重要的页面,因此Googlebot至少可以查看您网页上的内容 .

    Downsides

    • 设置起来更复杂

    • 对于那些给予特殊待遇的路线,只有优秀的搜索引擎优化

    • 复制用于在服务器和客户端上呈现内容的代码

    .

    同构

    如果我们使用Node JS作为我们的服务器,那么我们可以在两端运行相同的JS代码怎么办?现在,我们已经在一个反应路由器配置中定义了所有路由,可以说我们不知道圣杯 . 如果在客户端上发生页面转换,服务器将发送完全相同的标记 . 该解决方案在SEO方面是最佳的 .

    Downsides

    • 服务器必须(能够)运行JS . 我've experimented with Java i.c.w. Nashorn but it'不适合我 . 在实践中,它主要意味着您必须使用基于Node JS的服务器 .

    • 许多棘手的环境问题(在服务器端使用 window 等)

    • 陡峭的学习曲线

    .

    我应该使用哪个?

    选择你可以逃脱的那个 . 就我个人而言,我认为这个包罗万象足够简单,可以设置出最低限度 . 此设置允许您随着时间的推移改进 . 如果您已经使用Node JS作为服务器平台,我肯定会调查做同构应用程序 . 是的,一开始很难,但一旦掌握了它,它实际上是解决问题的一个非常优雅的解决方案 .

    所以基本上,对我来说,这将是决定性的因素 . 如果我的服务器在Node JS上运行,我会变得同构,否则我会选择Catch-all解决方案并随着时间的推移扩展它(混合解决方案)并且SEO要求它 .

    如果您想了解有关使用React进行同构(也称为“通用”)渲染的更多信息,可以参考以下主题:

    另外,为了帮助您入门,我建议您查看一些入门套件 . 选择一个符合您对技术堆栈的选择(请记住,React只是MVC中的V,您需要更多东西来构建完整的应用程序) . 首先看看Facebook本身发布的那个:

    或者从社区中挑选其中一个 . 现在有一个很好的网站试图索引所有这些:

    我从这些开始:

    目前我使用的是通用渲染的家庭酿造版本,其灵感来自上面的两个入门套件,但它们现在已经过时了 .

    祝你好运!

  • 14

    它很简单,当你得到刷新dom组件后无法获得403错误 . 只需在您的web pack配置中添加这一行,'historyApiFallback:true' . 这节省了我整整一天 .

  • 0

    -jimbotron的评论帮助了我,问题是.htaccess

    '这是帮助解决我的问题的参考:https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#serving-apps-with-client-side-routing - jimbotron'

  • 5

    Webpack Dev Server有一个选项来启用它 . 打开 package.json 并添加 --history-api-fallback . 这个解决方案对我有用 .

    https://github.com/reactjs/react-router-tutorial/tree/master/lessons/10-clean-urls#configuring-your-server

相关问题