客户端路由(使用BrowserRouter)与动态服务器反应无法正常工作

时间:2019-04-30 20:39:51

标签: reactjs react-router

我正在使用客户端路由(BrowserRouter)构建一个React应用。 服务器端是用python Flask(动态服务器)编写的。 由于某些原因,刷新某些页面/访问路由无法正常工作,仅返回index.html文件,但无法导航至window.location.href URL。

基于:https://facebook.github.io/create-react-app/docs/deployment

  

如果您使用的是在后台使用HTML5 pushState历史记录API的路由器   (例如,具有browserHistory的React Router),许多静态文件服务器将失败。例如,如果您将React Router与> / todos / 42的路由一起使用,则>开发服务器将响应localhost:3000 / todos / 42   正确,但服务于上述生产版本的Express不会。

     

这是因为当/ todos / 42重新加载页面时,服务器> build / todos / 42会查找文件,但找不到。该服务器需要配置为通过提供index.html来响应对/ todos / 42的请求。 >例如,我们可以修改上面的Express示例,为>未知路径提供index.html:

因此,我为浏览器请求的每个未知路径提供index.html。

也-我已将package.json中的首页属性设置为“。”。

我尝试添加的最后一件事-

devServer: {
    historyApiFallback: true
  }

到webpack.config.js

注意:我向我的应用添加了日志,并在App.js中添加了this.props.location的值 总是不确定的(不确定是否应该这样)。

index.js(我的应用程序中尚未使用Redux):

import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import "bootstrap/dist/css/bootstrap.min.css";
import "./App.css";

import { combineReducers, createStore } from "redux";
import { Provider } from "react-redux";
import targetsReducer from "./Reducers/targets-reducer";
import userReducer from "./Reducers/user-reducer";
import { BrowserRouter } from "react-router-dom";

const allReducers = combineReducers({
  targets: targetsReducer,
  user: userReducer
});

const store = createStore(
  allReducers,
  window.window.__REDUX_DEVTOOLS_EXTENSION__ &&
    window.window.__REDUX_DEVTOOLS_EXTENSION__()
);
// <Provider store={store}>
// </Provider>,

ReactDOM.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>,
  document.getElementById("root")
);

App.js:

import React, { Component } from "react";
import { Route, Switch } from "react-router-dom";
import "./App.css";

import Login from "./Components/Login";
import SidebarTest from "./Components/Sidebar";
import Navbar from "./Components/Navbar";
import Campaigns from "./Components/Campaigns";
import Targets from "./Components/Targets";


class App extends Component {
  constructor(proprs) {
    super(proprs);
    this.state = {
      identifier: "",
      isLoggedIn: false
    };

    this.setIsLoggedIn = this.setIsLoggedIn.bind(this);
  }

  componentDidMount() {
    console.log("In App componentDidMount.");
    console.log("current path by window:", window.location.href);
    console.log("current path by react (props.location):", this.props.location);
    console.log("component state:", this.state);
  }

  /*Function that passed to Login component that toggles the isLoggedIn state*/
  setIsLoggedIn(identifier) {
    this.setState(() => {
      return {
        identifier: identifier,
        isLoggedIn: !this.state.isLoggedIn
      };
    });
  }

  render() {
    console.log("In App render.");
    console.log("current path by window:", window.location.href);
    console.log("current path by react (props.location):", this.props.location);
    console.log("component state:", this.state);
    return (
      <div className="App">
        <div className="banner">
          <h1 id="banner-text">
            Uranus - Intelligence gathering and Attack system
          </h1>
        </div>
        {!this.state.isLoggedIn ? (
          <Route
            exact
            path="/"
            component={() => <Login setIsLoggedIn={this.setIsLoggedIn} />}
          />
        ) : (
          <div className="d-flex" id="page-container">
            <div className="sidebar-container">
              {this.state.isLoggedIn && <SidebarTest />}
            </div>
            <div className="navbar-and-data-container">
              <div className="navbar-container">
                {this.state.isLoggedIn && (
                  <Navbar identifier={this.state.identifier} />
                )}
              </div>
              <div className="data-container">
                <Switch>
                  <Route
                    exact
                    path="/Campaigns"
                    identifier={this.state.identifier}
                    component={Campaigns}
                  />
                  <Route
                    exact
                    path="/Targets/:campaignName"
                    component={Targets}
                  />
                </Switch>
              </div>
            </div>
          </div>
        )}
      </div>
    );
  }
}
export default App;


例如: 如果作为用户,我在“ /”中并且刷新页面,则我没有任何问题,显示的屏幕是“登录”页面。 但是,如果我在“ / campaigns”中,然后刷新页面,我希望该应用程序显示注册到“ / campaigns”的组件,但安装后我只会得到App.js中定义的横幅的页面

另一种情况,当我按下按钮时,使用URL =打开一个新窗口 我再次希望“ / Targets /:campaignName”看到在App.js文件中定义的此URL的注册组件,以确保我仅获得在App.js中定义的标语的页面

1 个答案:

答案 0 :(得分:0)

刷新/打开新标签页时,您可能会丢失状态isLoggedIn

您可以通过删除三元对象来检查它,以确保在刷新时呈现正确的组件。

您将如何坚持用户已登录的事实?通常是使用会话Cookie完成的。