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

IT技术 javascript html reactjs react-router
2021-05-16 02:23:46

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

我在这里这里找到了一些指针但到目前为止没有运气。这是一个常见问题吗?如何解决它?

我使用 webpack 开发服务器和由自耕农脚手架构建的默认配置

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

当我在http://localhost:8000/上加载我的应用程序时,一切都显示正常,然后我导航到http://localhost:8000/customer/ABCD1234/chat并且我的图标正常。字体已正确加载。

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

DOMLazyTree.js?019b:56 GET 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 中添加一个,但我在控制台中收到了一个很好的红色警告,所以可能不是最好的主意:

警告:不推荐使用自动设置 basename,并将在下一个主要版本中删除。的语义与 basename 略有不同。请在 createHistory 选项中明确传递基本名称

4个回答

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

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

相反,请尝试使用绝对路径:

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

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

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

另外,如果使用 webpack,您可以尝试publicPath在您的配置文件中像这样设置:

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

我有同样的问题。

  1. <base href="http://whatever">使用默认的 browserHistory标签添加到包含 react-router 的 HTML 的页面的头部

  2. 加载页面 - history.js 将输出 2 个错误,警告:<base href>不推荐使用自动设置 basename ,并将在下一个主要版本中删除。的语义与 basename 略有不同。请在 createHistory 选项中明确传递基本名称

  3. 更改 react-router history 以使用 history where history is const history = useRouterHistory(createHistory)({ basename: 'http://whatever' }),这应该可以解决问题(因为 basename 现在已明确传递)

  4. 重新加载页面

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

5/9 更新

就我而言。

索引.html

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

应用程序.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")
);

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

由于 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

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

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