如何使反应路由器与静态资产、html5 模式、历史 API 和嵌套路由一起工作?
Posted
技术标签:
【中文标题】如何使反应路由器与静态资产、html5 模式、历史 API 和嵌套路由一起工作?【英文标题】:How to make react router work with static assets, html5 mode, history API and nested routes? 【发布时间】:2016-08-23 17:21:00 【问题描述】:我以为我开始了解 React Router,但是在添加一个为其组件加载 css 的库时,我遇到了新问题。从我家导航到包含该组件的页面时一切正常,但是当我刷新它时,字体的 url 被破坏了......
我找到了一些指针 here 和 here 但到目前为止还没有运气。这是一个常见问题吗?如何解决它?
我使用 webpack 开发服务器,默认配置由 yeoman scaffolder 构建。
我使用的库是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'));
我还尝试在我的 index.html 中添加 <base href="/"/>
,但我在控制台中收到了一个很好的红色警告,所以这可能不是最好的主意:
警告:使用 is 自动设置 basename 已弃用并将在下一个主要版本中删除。这 的语义与 basename 略有不同。请 在 createHistory 的选项中显式传递基本名称
【问题讨论】:
【参考方案1】:听起来您已经在 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: '/'
,
...
【讨论】:
理论上,我认为这可行,但有问题的资产是一种字体,正如我提到的那样,由 font awesome 加载。而且我不能改变路径,除非我自己从 SCSS 构建了很棒的字体,但是我失去了 CDN 的优势......这是 CSS:maxcdn.bootstrapcdn.com/font-awesome/4.6.1/css/… 您将如何处理多种不同来源的静态资产。因为我认为我的问题可能来自类似的东西。由于 fontawsome 加载了相对路径,但我的图片来自绝对资产路径,就像你提到的那样...... 您在项目中使用的是纯 CSS 还是 SASS?如果是后者,我宁愿在我的项目中包含 font-awesome 并重新定义基本路径,而不是必须管理多个资产路径:fontawesome.io/get-started【参考方案2】:我也有同样的问题。
使用默认 browserHistory 将 <base href="http://whatever">
标签添加到包含 react-router 的 HTML 的页面的头部
加载页面 - history.js 将输出 2 个错误,警告:使用 <base href>
自动设置基本名称已被弃用,并将在下一个主要版本中删除。的语义与 basename 略有不同。请在创建历史的选项中明确传递基本名称
将 react-router 历史记录更改为使用历史记录为 const history = useRouterHistory(createHistory)( basename: 'http://whatever' )
的历史记录,这应该可以解决问题(因为 basename 现在已显式传递)
重新加载页面
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")
);
然后重新加载警告就消失了。 希望这是有用的。
【讨论】:
正如我在问题中提到的,我已经尝试过了,我确实找到了这个 github 问题。为了确定起见,我通过复制粘贴您的代码再次尝试,即使我做了您解释的第 3 步,我也会收到警告...【参考方案3】:感谢 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
【讨论】:
链接失效了。 没错:create-react-app.dev/docs/proxying-api-requests-in-development/… 嗨@BBaysinger,对不起,我没有注意到你的评论。感谢 skini827 更新链接【参考方案4】:我通过在应用索引页面上加载 font awesome cdn 解决了这个问题。然后它在所有情况下的所有路线上都可用。
【讨论】:
以上是关于如何使反应路由器与静态资产、html5 模式、历史 API 和嵌套路由一起工作?的主要内容,如果未能解决你的问题,请参考以下文章