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 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>
?它在这里使用完全是因为它不应该影响位置路径,只有哈希.
怎么解决这个问题?
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 次 |
最近记录: |