如何使 React 路由器与静态资产、html5 模式、历史记录 API 和嵌套路由一起工作?

How to make react router work with static assets, html5 mode, history API and nested routes?

我以为我开始理解 React Router,但是在添加一个为其组件加载 css 的库时,我遇到了新的障碍。从我的家导航到包含该组件的页面时一切正常,但是当我刷新它时,字体的 url 被破坏了...

我找到了一些指针 here and here,但到目前为止运气不好。这是一个常见问题吗?如何解决它?

我使用带有默认配置的 webpack 开发服务器 yeoman scaffolder

我使用的库是React Fa来显示图标。

当我在 http://localhost:8000/ everything displays fine, then I navigate to http://localhost:8000/customer/ABCD1234/chat 上加载我的应用程序时,我的图标没问题。字体已正确加载。

然后我刷新页面,我在控制台看到:

DOMLazyTree.js?019b:56 获取 http://localhost:8000/customer/ABCD1234/assets/926c93d201fe51c8f351e858468980c3.woff2

这显然是错误的,因为客户部分不应该在这里...

到目前为止,这是我的路由器:

ReactDOM.render(
  <Router history={browserHistory}>
    <Route path='/' component={App}>
      <IndexRoute component={Index}/>
      <Route path='customer/:id'        component={Customer}    />
      <Route path='customer/:id/chat'   component={CustomerChat}/>
      <Route path="*"                   component={ NotFound }  />
    </Route>
  </Router>
, document.getElementById('support-app'));

我也尝试将 <base href="/"/> 添加到我的 index.html,但我在控制台中收到一个很好的红色警告,所以这可能不是最好的主意:

Warning: Automatically setting basename using is deprecated and will be removed in the next major release. The semantics of are subtly different from basename. Please pass the basename explicitly in the options to createHistory

听起来您已经在 CSS 中定义了资源和图标的相对路径。

background-image: url('assets/image/myicon.png')

改为尝试绝对路径:

background-image: url('/assets/image/myicon.png')

由于 React 应用程序是单页应用程序,并且您在 / 上输入您的应用程序,因此无论您导航到哪个页面,所有 urls 都将正常工作,因为它们是相对于你开始的根。

但是一旦您在 /customer/ABCD 等不同路径上重新加载页面,您的所有资产都将与此相关,因此您在控制台中看到的是错误的 url。

此外,如果使用 webpack,您可以尝试在您的配置文件中设置 publicPath,如下所示:

...
output: {
    path: 'assets',
    publicPath: '/'
},
...

我也有同样的问题

  1. 使用默认的 browserHistory

  2. 在包含 react-router 的 HTML 的页面头部添加一个 <base href="http://whatever"> 标签
  3. 加载页面 - history.js 将输出 2 个错误,警告:不推荐使用 <base href> 自动设置基名,并将在下一个主要版本中删除。的语义与基本名称略有不同。请在 createHistory

  4. 的选项中明确传递基本名称
  5. 更改 react-router 历史记录以使用历史记录 const history = useRouterHistory(createHistory)({ basename: 'http://whatever' }),这应该可以解决问题(因为现在显式传递了 basename)

  6. 重新加载页面

https://github.com/reactjs/react-router/issues/3387

5/9 更新

以我为例。

index.html

<head>
  <base href="/" />
  <script src="app.js"></script>
</head>
<body>
  <div id="app">
  </div>
</body>

app.js

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

const browserHistory = useRouterHistory(createHistory)({ basename: '/' })

render(
  <Router routes={routes} history={browserHistory}/>,
  document.getElementById("app")
);

然后重新加载警告消失。 希望这是有用的。

我通过在应用程序索引页面上加载 font awesome cdn 解决了这个问题。然后它在所有情况下的所有路线上都可用。

感谢 react-script:2+

我解决了这个问题

你只需要创建一个名为setupProxy.js的js文件,它会被开发服务器加载。现在您可以完全控制您的代理:

const proxy = require('http-proxy-middleware');

module.exports = function(app) {
    console.log("configuring development proxies to point to localhost:4000")
    app.use(proxy('/api', { target: 'http://localhost:4000/' }));
    app.use(proxy('/graphql', { target: 'http://localhost:4000/' }));
};

https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#configuring-the-proxy-manually

编辑: 旧的 link 坏了,这是更新的: https://create-react-app.dev/docs/proxying-api-requests-in-development/#configuring-the-proxy-manually