2017-04-04 22 views
5

Tôi muốn thực hiện chuyển hướng trong các bộ chặn interceptor khi nhận được lỗi 403. Nhưng làm thế nào tôi có thể truy cập vào lịch sử bên ngoài các thành phần React?Làm thế nào để chuyển hướng từ máy đánh chặn trục với bộ phản ứng V4?

Trong Navigating Programatically in React-Router v4, đó là trong bối cảnh của một Phản ứng Component, nhưng ở đây tôi đang cố gắng trong bối cảnh Axios

axios.interceptors.response.use(function (response) { 
    // Do something with response data 
    return response; 
    }, function (error) { 
    // Do something with response error 
    if(error.response.status === 403) { console.log("Redirection needed !"); } 

    // Trow errr again (may be need for some other catch) 
    return Promise.reject(error); 
}); 
+0

mới Hãy thử với mã này: 'nhập {browserHistory} từ 'phản ứng-router ; 'then 'browserHistory.push ("/path ");' –

+0

Đã thử với 'import {browserHistory} từ' react-router-dom ';' sau đó' browserHistory.push ("/ path") 'và nó không hoạt động, đó là cách V3, phải không? –

+0

có không may điều này dường như không hoạt động cho bộ định tuyến V4 ... –

Trả lời

1

Các bạn đã thử vẽ một <Redirect>? Đó là cách tiêu chuẩn để chuyển hướng với v4. Tôi không chắc nơi mã của bạn tồn tại, nhưng miễn là bạn được nhập khẩu React nó sẽ hoạt động.

axios.interceptors.response.use(function (response) { 
    return response; 
    }, function (error) { 
    // Do something with response error 
    if(error.response.status === 403) { 
     return <Redirect to='/somePage' /> 
    } 

    // Trow errr again (may be need for some other catch) 
    return Promise.reject(error); 
}); 

Đây là tài liệu cho <Redirect>

+2

'return ' Không hiệu quả với tôi –

1

Giải pháp tốt nhất tôi thấy là xác định axios.interceptors bên Phản ứng thành phần chính của tôi và sử dụng that để xử lý các lỗi: (Và với withRouter từ Router V4)

import {withRouter} from 'react-router-dom'; 

class Homepage extends Component { 
    static propTypes = { 
    history: PropTypes.object.isRequired 
    } 

    constructor(props){ 
    super(props); 

    let that = this; 
    axios.interceptors.response.use(function (response) { 
     // Do something with response data 
     return response; 
     }, function (error) { 
     // Do something with response error 
     if(error.response.status === 403) { that.handle403() } 

     // Trow errr again (may be need for some other catch) 
     return Promise.reject(error); 
    }); 

    } 

    handle403(){ 
    this.props.history.push('/login'); 
    } 
7

Tôi đã giải quyết điều đó bằng cách truy cập Cửa hàng Redux của mình từ bên ngoài cây Thành phần và gửi tác vụ tương tự của tôi từ nút đăng xuất, vì trình chặn của tôi được tạo trong một tệp được phân tách và được tải trước khi bất kỳ Thành phần nào được tải.

Vì vậy, về cơ bản, tôi đã làm như sau:

Tại index.js file:

//....lots of imports ommited for brevity 
import { createStore, applyMiddleware } from 'redux'; 
import reduxThunk from 'redux-thunk'; 
import reducers from './reducers'; 
import { UNAUTH_USER } from './actions/types'; //this is just a constants file for action types. 

const createStoreWithMiddleware = applyMiddleware(reduxThunk)(createStore); 
const store = createStoreWithMiddleware(reducers); 

//Here is the guy where I set up the interceptors! 
NetworkService.setupInterceptors(store); 

//lots of code ommited again... 
//Please pay attention to the "RequireAuth" below, we'll talk about it later 

ReactDOM.render(
    <Provider store={store}> 
     <BrowserRouter> 
      <div> 
       <Header /> 
       <main className="plan-container"> 
        <Switch> 
         <Route exact path="/" component={Landing} /> 
         <Route exact path="/login" component={Login} /> 
         <Route exact path="/signup" component={Signup} /> 
         <Route exact path="/calendar" component={RequireAuth(Calendar)} /> 
         <Route exact path="/profile" component={RequireAuth(Profile)} /> 
        </Switch> 
       </main> 
      </div> 
     </BrowserRouter> 
    </Provider> 
    , document.querySelector('.main-container')); 

Và tại network-service.js file:

import axios  from 'axios'; 
import { UNAUTH_USER } from '../actions/types'; 

export default { 
    setupInterceptors: (store) => { 

    // Add a response interceptor 
    axios.interceptors.response.use(function (response) { 
     return response; 
    }, function (error) { 
     //catches if the session ended! 
     if (error.response.data.token.KEY == 'ERR_EXPIRED_TOKEN') { 
      console.log("EXPIRED TOKEN!"); 
      localStorage.clear(); 
      store.dispatch({ type: UNAUTH_USER }); 
     } 
     return Promise.reject(error); 
    }); 

    } 
}; 

Cuối cùng nhưng không kém phần quan, tôi có một HOC (Thành phần thứ tự cao hơn) mà tôi bọc các thành phần được bảo vệ của mình nơi tôi thực hiện chuyển hướng thực sự khi phiên làm việc hết. Bằng cách đó, khi tôi kích hoạt loại hành động UNAUTH_USER, nó đặt thuộc tính isLogged của tôi tại số session giảm tốc thành false và do đó thành phần này được thông báo và chuyển hướng cho tôi, bất kỳ lúc nào.

Hồ sơ require-auth.js thành phần:

import React, { Component } from 'react'; 
import { connect } from 'react-redux'; 

export default function(ComposedComponent) { 

    class RequireAuth extends Component { 

     componentWillMount() { 
      if(!this.props.session.isLogged) { 
       this.props.history.push('/login'); 
      } 
     }; 

     componentWillUpdate(nextProps) { 
      if(!nextProps.session.isLogged) { 
       this.props.history.push('/login'); 
      } 
     }; 

     render() { 
      return <ComposedComponent {...this.props} /> 
     } 
    } 

    function mapStateToProps(state) { 
     return { session: state.session }; 
    } 

    return connect(mapStateToProps)(RequireAuth); 
} 

Hy vọng rằng sẽ giúp!

0

Tôi đang sử dụng phản ứng-router-dom và nó có "lịch sử" đạo cụ có thể được sử dụng trong quá trình chuyển đổi để định tuyến

history.push('/newRoute') 
Các vấn đề liên quan