gpt4 book ai didi

javascript - React Router 的 HashRouter 重定向到 标签 url

转载 作者:可可西里 更新时间:2023-11-01 02:43:32 25 4
gpt4 key购买 nike

我有非 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>
);
}
}

出于测试目的,可以禁用所有路由,但这不会改变行为。

Here is create-react-app project这表明了问题。复制它的步骤是:

  • npm i
  • npm start
  • 导航到 http://localhost:3000/some/static/page

HashRouter 明显受到 <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> 影响?它在这里使用正是因为它不应该影响位置路径,只会影响哈希。

如何解决这个问题?

最佳答案

其实这个来自history .如果你看到 their code , 他们只使用 createHashHistory并设置 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>
);
}
}

它将显示您遇到的相同问题。那么如果你改变 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))
});

那么你的问题就会消失,但绝对不能使用 hash .所以问题不在于 HashRouter但来自 history .

因为这个来自history ,让我们看看这个 thread .阅读该主题后,我们可以得出结论,这是来自 history功能 .

因此,如果您设置 <base href="/"> ,因为您正在使用 hash (#),当浏览器加载时(实际上是在 componentDidMount 之后)它会附加 hash (#) 在你的情况下 some/static/page => some/static/page + / => / + #/ => /#/ .可以打卡componentDidMount设置 debugger在追加路线之前 catch 。


解决方案

简单地说,删除元素<base href>或者不要使用 HashRouter .

如果仍然需要但希望避免特定的 component , 把这个放在 class 之前:

const base = document.querySelector("base");
base.setAttribute('href', '');

更新

因为你想保留base标记以保持持久链接并使用 hash路由器,这是我认为最接近的解决方案。

<强>1。设置标签 base清空。

const base = document.querySelector('base');
base.setAttribute('href', '');

将该代码放入 App组件(根包装组件)调用一次。

<强>2。当componentDidMount把它放回去

componentDidMount() {
setTimeout(() => {
base.setAttribute('href', '/');
}, 1000);
}

使用超时等待 react 完成渲染虚拟 dom。

我认为这非常接近(已测试)。因为你正在使用 hash路由器,来自索引 html 的链接将是安全的(不会被 react 覆盖,但会保留 base 标签)。它也适用于 css 链接 <link rel="stylesheet" href="styles.css">

关于javascript - React Router 的 HashRouter 重定向到 <base> 标签 url,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49467305/

25 4 0