如何在React-Router中从ajax调用中获取401错误时重定向到登录页面?

Chr*_*ris 5 ajax superagent reactjs react-router

我正在使用React,React-Router和Superagent.我的Web应用程序中需要授权功能.现在,如果令牌过期,我需要将页面重定向到登录页面.

我已将ajax调用功能放在一个单独的模块中,并且令牌将在每个请求的标头上发送.在我的一个组件中,我需要通过ajax调用获取一些数据,如下所示.

 componentDidMount: function() {

    api.getOne(this.props.params.id, function(err, data) {
      if (err) {
        this.setErrorMessage('System Error!');
      } else if (this.isMounted()) {
        this.setState({
          user: data
        });
      }
    }.bind(this));

  },
Run Code Online (Sandbox Code Playgroud)

如果我收到401(未授权)错误,可能是因为令牌过期或没有足够的权限,该页面应重定向到登录页面.现在,在我的api模块中,我必须使用window.loication="#/login"我不认为这是一个好主意.

var endCallback = function(cb, err, res) {

  if (err && err.status == 401) {
    return window.location('#/login');
  }

  if (res) {
    cb(err, res.body);
  } else {
    cb(err);
  }
};

get: function(cb) {
  request
    .get(BASE_URL + resources)        
    .end(endCallback.bind(null, cb));
},
Run Code Online (Sandbox Code Playgroud)

但是,我不能轻易地在我的api模块中调用react-router方法.有没有一种优雅的方式来实现这个简单的功能?我不想在每个需要授权的反应组件中添加错误回调.

Bra*_*ugh 3

我会尝试这样的事情:

  1. 使用组件的上下文来操作路由器 ( this.context.router.transitionTo())。
  2. 将此方法作为参数传递给 API 标注。

// component.js
,contextTypes: {
  router: React.PropTypes.func
},
componentDidMount: function() {
    api.getOne(this.props.params.id, this.context.router, function(err, data) {
      if (err) {
        this.setErrorMessage('System Error!');
      } else if (this.isMounted()) {
        this.setState({
          user: data
        });
      }
    }.bind(this));
},


// api.js
var endCallback = function(cb, router, err, res) {

  if (err && err.status == 401) {
    return router.transitionTo('login');
  }

  if (res) {
    cb(err, res.body);
  } else {
    cb(err);
  }
};

get: function(cb, router) {
  request
    .get(BASE_URL + resources)        
    .end(endCallback.bind(null, cb, router));
},
Run Code Online (Sandbox Code Playgroud)

我知道您不希望在每个经过身份验证的组件上进行回调,但我认为没有任何特殊的反应路由器快捷方式可以在路由器之外进行转换。

我唯一能想到的另一件事是在错误发生时启动一个全新的路由器并手动将其发送到登录路由。但我认为这不一定有效,因为它超出了初始渲染方法。