110

使用 react-router 时有什么方法可以防止/#/在浏览器的地址栏中显示?这就是 ReactJS。即点击链接去一个新的路线显示localhost:3000/#/localhost:3000/#/about。视路线而定。

4

6 回答 6

79

对于 react-router 的版本 1、2 和 3,将路由设置为 URL 映射方案的正确方法是将历史实现传递history<Router>. 从历史文档中:

简而言之,历史知道如何监听浏览器地址栏的变化,并将 URL 解析为一个位置对象,路由器可以使用该对象来匹配路由并呈现正确的组件集。

版本 2 和 3

在 react-router 2 和 3 中,您的路由配置代码将如下所示:

import { browserHistory } from 'react-router'
ReactDOM.render (( 
 <Router history={browserHistory} >
   ...
 </Router> 
), document.body);

版本 1

在版本 1.x 中,您将改为使用以下内容:

import createBrowserHistory from 'history/lib/createBrowserHistory'
ReactDOM.render (( 
  <Router history={createBrowserHistory()} >
   ...
  </Router> 
), document.body);

来源:2.0 版升级指南

版本 4

对于即将发布的第 4 版 react-router,语法发生了很大变化,需要BrowserRouter用作路由器根标记。

import BrowserRouter from 'react-router/BrowserRouter'
ReactDOM.render (( 
  <BrowserRouter>
   ...
 <BrowserRouter> 
), document.body);

React 路由器版本 4 文档

于 2015-10-13T17:29:52.673 回答
40
Router.run(routes, Router.HistoryLocation, function (Handler) {
  React.render(<Handler/>, document.body);
});

对于当前版本 0.11 及更高版本,您需要Router.HistoryLocation添加Router.run(). <Routes>现在已弃用。请参阅 0.12.x HistoryLocation 实施的升级指南

于 2014-11-29T07:37:15.883 回答
21

如果不需要支持 IE8,可以使用 Browser History,react-router 会使用window.pushState而不是设置 hash。

具体如何执行取决于您使用的 React Router 版本:

于 2014-08-01T19:13:38.467 回答
10

您实际上可以使用 .htaccess 来完成此操作。浏览器通常需要查询字符串分隔符?#确定查询字符串的开始位置和目录路径的结束位置。我们想要的最终结果是www.mysite.com/dir 所以我们需要在 Web 服务器搜索它认为我们请求的目录之前发现问题/dir。所以我们.htaccess在项目的根目录下放置一个文件。

    # Setting up apache options
    AddDefaultCharset utf-8
    Options +FollowSymlinks -MultiViews -Indexes
    RewriteEngine on

    # Setting up apache options (Godaddy specific)
    #DirectoryIndex index.php
    #RewriteBase /


    # Defining the rewrite rules
    RewriteCond %{SCRIPT_FILENAME} !-d
    RewriteCond %{SCRIPT_FILENAME} !-f

    RewriteRule ^.*$ ./index.html

然后使用 window.location.pathname 获取查询参数

然后,您可以根据需要避免使用 react 路由,并且如果需要也可以操作 url 和浏览器历史记录。希望这可以帮助某人...

于 2016-01-21T01:02:00.377 回答
5

安装历史包

npm install history --save

接下来从历史中导入 createHistory 和 useBasename

import { createHistory, useBasename } from 'history';
...
const history = useBasename(createHistory)({
  basename: '/root' 
});

如果您的应用程序 url 是 www.example.com/myApp,那么 /root 应该是 /myApp。

将历史变量传递给路由器

render((
  <Router history={history}>
    ...
  </Router>
), document.getElementById('example'));

现在,对于所有链接标签,在所有路径前附加一个“/”。

<Link to="/somewhere">somewhere</Link>

该解决方案的灵感来自React-Router 示例 ,不幸的是,该示例没有正确记录在他们的 API 中。

于 2016-01-30T02:27:37.610 回答
3

另一种处理散列后显示的内容的方法(所以如果你不使用 pushState !)是创建你的 CustomLocation 并在 ReactRouter 创建时加载它。

例如,如果你想让 hashbang url (所以用 #!) 来遵守谷歌的抓取规范,你可以创建一个 HashbangLocation.js 文件,它主要复制原始的 HashLocation,例如:

'use strict';

var LocationActions = require('../../node_modules/react-router/lib/actions/LocationActions');
var History = require('../../node_modules/react-router/lib/History');

var _listeners = [];
var _isListening = false;
var _actionType;

function notifyChange(type) {
  if (type === LocationActions.PUSH) History.length += 1;

  var change = {
    path: HashbangLocation.getCurrentPath(),
    type: type
  };

  _listeners.forEach(function (listener) {
    listener.call(HashbangLocation, change);
  });
}

function slashToHashbang(path) {
  return "!" + path.replace(/^\//, '');
}

function ensureSlash() {

  var path = HashbangLocation.getCurrentPath();
  if (path.charAt(0) === '/') {
    return true;
  }HashbangLocation.replace('/' + path);

  return false;
}

function onHashChange() {
  if (ensureSlash()) {
    // If we don't have an _actionType then all we know is the hash
    // changed. It was probably caused by the user clicking the Back
    // button, but may have also been the Forward button or manual
    // manipulation. So just guess 'pop'.
    var curActionType = _actionType;
    _actionType = null;
    notifyChange(curActionType || LocationActions.POP);
  }
}

/**
 * A Location that uses `window.location.hash`.
 */
var HashbangLocation = {

  addChangeListener: function addChangeListener(listener) {
    _listeners.push(listener);

    // Do this BEFORE listening for hashchange.
    ensureSlash();

    if (!_isListening) {
      if (window.addEventListener) {
        window.addEventListener('hashchange', onHashChange, false);
      } else {
        window.attachEvent('onhashchange', onHashChange);
      }

      _isListening = true;
    }
  },

  removeChangeListener: function removeChangeListener(listener) {
    _listeners = _listeners.filter(function (l) {
      return l !== listener;
    });

    if (_listeners.length === 0) {
      if (window.removeEventListener) {
        window.removeEventListener('hashchange', onHashChange, false);
      } else {
        window.removeEvent('onhashchange', onHashChange);
      }

      _isListening = false;
    }
  },

  push: function push(path) {
    _actionType = LocationActions.PUSH;
    window.location.hash = slashToHashbang(path);
  },

  replace: function replace(path) {
    _actionType = LocationActions.REPLACE;
    window.location.replace(window.location.pathname + window.location.search + '#' + slashToHashbang(path));
  },

  pop: function pop() {
    _actionType = LocationActions.POP;
    History.back();
  },

  getCurrentPath: function getCurrentPath() {
    return decodeURI(
    // We can't use window.location.hash here because it's not
    // consistent across browsers - Firefox will pre-decode it!
    "/" + (window.location.href.split('#!')[1] || ''));
  },

  toString: function toString() {
    return '<HashbangLocation>';
  }

};

module.exports = HashbangLocation;

注意slashToHashbang函数。

然后你只需要做

ReactRouter.create({location: HashbangLocation})

就是这样:-)

于 2015-08-20T15:31:13.397 回答