Est*_*ask 10 javascript base-tag base-url reactjs react-router
我有非SPA服务器端应用程序与React应用程序,仅限于当前页面,/some/static/page.应用程序<base href="/">在<head>所有页面上都依赖于它,这是无法更改的.
以下是React 16,React Router 4的基本示例<HashRouter>:
export class App extends React.Component {
render() {
return (
<HashRouter>
<div>
<Route exact path="/" component={Root} />
</div>
</HashRouter>
);
}
}
Run Code Online (Sandbox Code Playgroud)
可以禁用所有路由以进行测试,但这不会更改行为.
这是create-react-app显示问题的项目.复制它的步骤是:
npm inpm starthttp://localhost:3000/some/static/pageHashRouter显然受到影响<base>.它重定向/some/static/page到/#/初始化,而我期望它是/some/static/page#/或/some/static/page/#/(只在IE 11中工作).
Root组件在重定向之前会快速启动/#/.
它重定向到/foo/#/的情况下<base href="/foo">,并重定向到/some/static/page/#/当<base>标签被删除.
问题影响Chrome和Firefox(最新版本),但不影响Internet Explorer(IE 11).
为什么<HashRouter>受到影响<base>?它在这里使用完全是因为它不应该影响位置路径,只有哈希.
怎么解决这个问题?
hen*_*ngs 10
其实这从history。如果你看到他们的代码,他们使用 justcreateHashHistory和 set children。所以它相当于:
import React from 'react';
import { Route, Router } from 'react-router-dom';
import { createHashHistory } from 'history';
const Root = () => <div>Root route</div>;
export default class App extends React.Component {
history = createHashHistory({
basename: "", // The base URL of the app (see below)
hashType: "slash", // The hash type to use (see below)
// A function to use to confirm navigation with the user (see below)
getUserConfirmation: (message, callback) => callback(window.confirm(message)),
});
render() {
return (
<Router history={this.history}>
<div>Router
<Route exact path="/" component={Root} />
</div>
</Router>
);
}
}
Run Code Online (Sandbox Code Playgroud)
它会显示您遇到的相同问题。然后,如果您history像这样更改代码:
import {createBrowserHistory } from 'history';
...
history = createBrowserHistory({
basename: "", // The base URL of the app (see below)
forceRefresh: false, // Set true to force full page refreshes
keyLength: 6, // The length of location.key
// A function to use to confirm navigation with the user (see below)
getUserConfirmation: (message, callback) => callback(window.confirm(message))
});
Run Code Online (Sandbox Code Playgroud)
那么你的问题会消失但绝对不会使用hash。所以问题不是来自
HashRouter而是来自history.
因为这来自history,让我们看看这个线程。读线程之后,我们可以采取的结论,这是功能的history。
所以,如果你设置了<base href="/">,因为你正在使用hash(#),当浏览器加载时(实际上是之后componentDidMount)它会hash在你的情况下附加(#) some/static/page=> some/static/page+ /=> /+ #/=> /#/。您可以在附加路由之前检查componentDidMount设置debugger以捕获。
简单地说,只需删除元素<base href>或不使用HashRouter.
如果仍然需要但想避免特定的component,只需将其放在之前class:
const base = document.querySelector("base");
base.setAttribute('href', '');
Run Code Online (Sandbox Code Playgroud)
由于您想保留base标签以保持链接并使用hash路由器,因此我认为这是关闭的解决方案。
1. 将标签设置base为空。
const base = document.querySelector('base');
base.setAttribute('href', '');
Run Code Online (Sandbox Code Playgroud)
将该代码放在App组件(根包装组件)中以调用一次。
2.什么时候componentDidMount放回去
componentDidMount() {
setTimeout(() => {
base.setAttribute('href', '/');
}, 1000);
}
Run Code Online (Sandbox Code Playgroud)
使用超时等待反应完成渲染虚拟 dom。
这非常接近,我想(测试一下)。因为您使用的是hash路由器,所以来自索引 html 的链接将是安全的(不是通过反应覆盖而是通过base标签保留)。它也适用于 css 链接<link rel="stylesheet" href="styles.css">。
| 归档时间: |
|
| 查看次数: |
6922 次 |
| 最近记录: |