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

例如,我在localhost/joblist和一切都很好,因为我到达这里按下一个链接。但如果我刷新网页,我会得到:

Cannot GET /joblist

默认情况下,它不是这样工作的。最初我有我的URL localhost/#/和localhost/#/joblist,他们工作得很好。但我不喜欢这种类型的URL,所以试图删除#,我写道:

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

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

这个应用程序是单页的,所以/joblist不需要向任何服务器询问任何事情。

我的整个路由器。

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

当前回答

你可以在你的React应用程序中使用Vercel的主机,并使用相同的旧方式在你的React应用程序中使用BrowserRouting。

您需要添加一个vercel。Json文件在你的项目的根,并添加以下代码:

{
  "rewrites": [
    {
      "source": "/((?!api/.*).*)",
      "destination": "/index.html"
    }
  ]
}

这工作得非常好。

其他回答

我也遇到过同样的问题,这个解决方案对我们很有效……

背景:

我们在同一台服务器上托管多个应用程序。当我们刷新服务器时,它不知道该在目标文件夹的哪个位置查找特定应用程序的索引。上面的链接将把你带到我们的工作…

我们正在使用:

文件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文件:

/* 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文件

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!');
});

如果你有一个回退到你的index.html,确保在你的index.html文件中你有这个:

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

这可能因项目而异。

我用React路由器(Apache)为我的SPA找到了解决方案。只要在文件.htaccess中添加这个:

<IfModule mod_rewrite.c>

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

</IfModule>

来源:Apache的React路由器配置

用Laravel在React中实现JavaScript SPA的解决方案

公认的答案是对为什么会发生这样的问题的最好解释。如前所述,您必须同时配置客户端和服务器端。

在你的blade模板中,包括JavaScript绑定文件,确保像这样使用URL外观:

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

在路由中,确保将此添加到刀片模板所在的主端点。例如,

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

以上是刀片模板的主要端点。现在再添加一条可选路线,

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

发生的问题是,首先加载刀片模板,然后加载React路由器。当你加载'/setting-alerts'时,它会加载HTML内容和JavaScript代码。

但是当你加载'/setting-alerts/about'时,它首先在服务器端加载。因为它在服务器端,所以这个位置上没有任何东西,并且它返回not found。当你有可选的路由器时,它加载同一个页面,React路由器也被加载,然后React加载器决定显示哪个组件。

在后端使用Express.js,在前端使用React(没有React -create-app)和reach/router,正确的reach/router路由React组件会显示出来,当在地址栏中点击Enter时,菜单链接将被设置为活动样式,例如http://localhost:8050/pages。

请签出以下内容,或直接访问我的存储库https://github.com/nickjohngray/staticbackeditor。所有的代码都在那里。

网络包:

设置代理。这允许任何从端口3000 (React)调用服务器, 包括当按下回车键时在地址栏中获取index.html或任何东西的调用。它还允许调用API路由来获取JSON数据。

比如await axios。Post ('/api/login', {email, pwd}):

devServer: {
    port: 3000,
    open: true,
    proxy: {
      '/': 'http://localhost:8050',
    }
  }

设置Express.js路由

app.get('*', (req, res) => {
    console.log('sending index.html')
    res.sendFile(path.resolve('dist', 'index.html'))

});

这将匹配React的任何请求。它只返回dist文件夹中的index.html页面。当然,这个页面有一个更单页的React应用程序。(注意任何其他路由都应该出现在这个上面,在我的情况下,这些是我的API路由。)

反应路线

<Router>
    <Home path="/" />
    <Pages path="pages"/>
    <ErrorPage path="error"/>
    <Products path="products"/>
    <NotFound default />
</Router>

这些路由是在我的布局组件中定义的,当路径匹配时,该组件将加载相应的组件。

React布局构造函数

constructor(props) {
    super(props);

    this.props.changeURL({URL: globalHistory.location.pathname});
}

Layout构造函数在加载时立即被调用。在这里,我调用我的redux操作changeURL,我的菜单监听,所以它可以突出显示正确的菜单项,如下所示:

菜单的代码

<nav>
    {this.state.links.map( (link) =>
    <Link className={this.getActiveLinkClassName(link.path) } to={link.path}>
      {link.name}
    </Link>)}
</nav>