可以使用 browserHistory 反应单页应用程序吗?

React Single Page app with browserHistory possible?

我一直在使用 react-router 中的 hashHistory 构建一个 React 单页应用程序,并且一切正常,直到我决定删除 URL 中的尾随代码看起来像这样:#/?_k=ncbx6v.

我遇到的推荐解决方案是过渡到 browserHistory,但我注意到所有示例和解决方案都需要使用 webpack-dev-server 并将 history-api-fallback 设置为 true。我尝试了这种方法并且它有效(通过 localhost),但是独立的 bundle.js 文件 + index.html 曾经有效的不再有效。

当我 运行 webpack 并打开 html 文件时,我在控制台中收到此错误: Warning: [react-router] Location "/Users/mike/project/index.html" did not match any routes

我不熟悉这个问题背后的机制,但我很好奇是否有我不熟悉的解决方案。

这是我的 webpack 文件:

const {resolve} = require('path')

module.exports = () => {
  return {
    context: resolve('src'),
    entry: './app',
    output: {
      path: resolve('public'),
      filename: 'bundle.js',
      publicPath: '/public/'
    },
    resolve: {
      extensions: ['.js', '.jsx', '.json']
    },
    stats: {
      colors: true,
      reasons: true,
      chunks: false
    },
    module: {
      rules: [
        {enforce: 'pre', test: /\.jsx?$/, loader: 'eslint-loader', exclude: [/node_modules/]},
        {test: /\.jsx?$/,loader: 'babel-loader', include: /src/, exclude: /node_modules/
        },
        {test: /\.json$/, loader: 'json-loader'},
        {test: /(\.css)$/, loaders: ['style-loader', 'css-loader']},
        {test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: "file-loader"},
        {test: /\.(woff|woff2)$/, loader: "url-loader?prefix=font/&limit=5000"},
        {test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: "url-loader?limit=10000&mimetype=application/octet-stream"},
        {test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: "url-loader?limit=10000&mimetype=image/svg+xml"}
      ]
    }
  }
}

这是我的 app.js:

'use strict'
import React from 'react'
import ReactDOM from 'react-dom'
import Layout from './components/common/Layout'
import { Router, Route, IndexRoute, browserHistory } from 'react-router'
import configureStore from './store/configureStore'
import { Provider } from 'react-redux'

const store = configureStore()

class App extends React.Component {
  render () {
    return (
      <Provider store={store}>
        <Router history={browserHistory}>
          <Route path='/' component={Layout}></Route>
        </Router>
      </Provider>
    )
  }
}

ReactDOM.render(<App />, document.getElementById('app'))

为了使用浏览器历史记录,您需要一个可以处理所有可能路由的后端。如果您不打算拥有支持路由的后端(例如,您将提供静态文件),您应该坚持哈希历史。

浏览器历史记录如何工作的基本解释是它查看当前 URL 的 pathname 并尝试将其与已知路由相匹配。在您包含的错误中,您的 pathname/Users/mike/project/index.html。这意味着为了让 React Router 匹配 URL,你必须定义 <Route>path(或者有一系列嵌套的 <Route>)成为 /Users/mike/project/index.html.

<Route path='Users/mike/project/index.html' component={App} />

哈希历史适用于静态文件,因为它只是在 pathname 之后附加一个哈希符号,并根据后面的内容确定路由。

如果您的问题只是您不喜欢查询键(?_k=jkadjlkd),您可以指定在 create your history instance 时不应包含该键。 URL 仍将包含 #,但不再附加密钥 "junk"。

import { Router, useRouterHistory } from 'react-router'
import { createHashHistory } from 'history'

const appHistory = useRouterHistory(createHashHistory)({ queryKey: false })
<Router history={appHistory} />