我有一个简单的react应用,该应用正在使用第三个API来获取数据。在发出任何请求之前,必须检索令牌以便在标头中使用它。该令牌是通过传递客户端ID和密钥ID使用相同的API来创建的-该API是Artsy API。该令牌具有到期日期,因此如果该令牌不存在,则必须请求此API。获取令牌后,我可以毫无问题地调用其他请求。
我将API请求设置在一个单独的文件中,如下所示: Apis.js
import Axios from 'axios';
const baseURL = 'https://api.artsy.net/api';
// set up xap-token and set tot default headers
const instance = Axios.create({
baseURL: baseURL + '/tokens/xapp_token',
params: {
'client_id': process.env.CLIENTID,
'client_secret': process.env.CLIENTSECRET
}
});
instance.interceptors.request.use(undefined, err => {
const status = err.response ? err.response.status : null;
console.log("auth",err.response)
if(status === 401){
console.log("auth",err.response)
return 'hello'
// this.getAuthToken();
}
});
export default{
getArtworks: function(){
return new Promise((resolve, reject) => {
instance.get(baseURL + '/artworks')
.then(res => {
resolve(res)
})
.catch(err => {
reject(err);
});
});
},
getArtists: function(){
return new Promise((resolve, reject) => {
instance.get(baseURL + '/artists')
.then(res => {
resolve(res)
})
.catch(err => {
reject(err);
});
});
},
getTest: function(){
return 'hello';
}
};
不确定如何使用create
和interceptors
,但是我创建了一个Axios实例。因此,其想法是创建某种中间件,创建一个实例,然后在该错误有请求时将其用作拦截器。如果存在,则将令牌应用于该实例并继续进行请求retry
。同样不确定如何在实例中设置令牌。
到目前为止,我在getArtists
方法中遇到401错误,该API在页面加载时被调用,它位于componentDidMount
下。
App.jsx
import React, { Component } from 'react';
import Apis from './utils/Api';
import Gallery from './components/Gallery';
class App extends Component{
constructor(props){
super(props);
this.state = {
artWorks: []
}
}
componentDidMount = () => {
// Apis.getArtists();
Apis.getArtists().then(res => {
console.log(res)
// this.setState({
// artWorks: res.data
// })
});
}
render(){
return(
<div>
<Gallery artists={this.state.artWorks}/>
</div>
)
}
}
export default App;
这是用于认证的api文档链接。
有人可以帮忙吗?不太确定如何将实例用作“中间件”? Axios的新功能。我想避免使用3rd库中间件,我更喜欢以手动方式学习而不是使用3rd库。非常感谢您的帮助
更新:
我能够使它工作一些,我修改了instance.interceptor
:
instance.interceptors.response.use(undefined, err => {
const status = err.response ? err.response.status : null;
if(status === 401){
console.log("auth",err.response)
instance.post(err.config.authURL, err.config.auth).then(res => {
let token = res.data.token;
err.config.headers['X-XAPP-Token'] = token;
console.log('calling',err.response)
return instance.request(err.config)
});
}
// return Promise.reject(err);
});
但是我在getArtists
响应中不确定。不知道这是怎么回事。这是控制台的屏幕截图:
答案 0 :(得分:1)
即使我遇到了同样的问题,也可以通过使用以下代码解决
export const instance = axios.create({ baseURL: API_BASE_URL })
const instance = axios.create();
instance.interceptors.response.use((response) => {
console.log(`response ${response}`);
return response;
}, (error) => {
console.log(`error ${error}`);
return Promise.reject(error);
});
instance.interceptors.request.use(
(config) => {
if (this.isUserLoggedIn()) {
localStorage.setItem(APP_TOKEN, token)
config.headers.Authorization = token
}
return config
}
)
答案 1 :(得分:0)
您应该使用instance.interceptors.response
而不是instance.interceptors.request
。
因为在发送Ajax请求之前调用了请求拦截器。我认为响应拦截器实际上就是您想要的。
const instance = Axios.create({
baseURL: 'https://api.artsy.net/api'
})
// because you set the baseURL of the instance
// this will request url https://api.artsy.net/api/artworks
instance.get('/artworks')
instance.post('tokens/xapp_token').then(res => {
/* here is the response
{
"type" : "xapp_token",
"token" : "...",
"expires_at" : "2014-09-05T12:39:09.200Z"
}
*/
// you can set common request headers like this
// or use request interceptors here to set headers
// then every request you sent by instance after will have X-XAPP-Token header
instance.defaults.headers.common['X-XAPP-Token'] = res.token
})
实际上err.config.headers['X-XAPP-Token'] = token;
该代码不会影响请求标头。