django - 无法理解反应中的 axios 错误处理
问题描述
我正在学习 react 和 django。我已经安装了django-rest-auth来处理用户的帐户创建和身份验证。我也想了解反应,我已经安装了 axios来向我的 django rest api 发出 http 请求。我希望有一个“启动”页面,用户将首先访问该站点。如果用户已经登录,他们将看到他们的个人资料和其他内容。如果用户没有登录,他们应该看到一个登录页面。
这是我到目前为止的 App.js 代码。
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import logo from './logo.svg';
import './App.css';
function LoginPage(props) {
console.log('LoginPage props are:');
console.log({ props });
return (<div className="LoginPage">props are: {props}</div>)
}
function SplashPage(props) {
const [currentUser, setCurrentUser] = useState(null);
console.log('SplashPage props are:');
console.log({ props });
const userUrl = 'http://localhost:8000/rest-auth/user/';
console.log('userUrl is:' + userUrl);
axios.get(userUrl)
.then(res => { setCurrentUser(res.data); })
.catch((error) => {
console.log(error.response);
return (<div><LoginPage /></div>);
})
return (<div className="SplashPage">[{userUrl}] [{currentUser}] </div>);
}
function App() {
return (
<div>
<SplashPage />
</div>
);
}
export default App;
这是我的 index.js 文件:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
ReactDOM.render(<App />, document.getElementById('root'));
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers:
serviceWorker.unregister();
当我去http://localhost:3000
我得到这个结果:
在开发者控制台中看起来像
我曾希望看到我的LoginPage
功能的内容。
解决方案
[更新答案]
您<div className="SplashPage">[{userUrl}] [{currentUser}] </div>
之前返回<div><LoginPage /></div>
是因为它在 axios .then() 链之外(即它直接在 axios.get() 之后和 .then() 或 .catch() 块中的任何代码之前调用)
应该管用:
- 使用 loaderState 初始化当前用户以避免内容闪烁
- 在 axios .then() 或 .catch() 中更新状态
- 使用 state 来确定从 promise 之外的函数返回什么
-
function SplashPage(props) {
const [currentUser={notLoaded:true}, setCurrentUser] = useState(null);
const userUrl = 'http://localhost:8000/rest-auth/user/';
axios.get(userUrl).then(res => {
setCurrentUser(res.data);
}).catch((error) => {
console.log(error)
setCurrentUser(null)
})
//user no authorized
if(!currentUser)
return <LoginPage />
//user authorization unknown
if(currentUser.notLoaded)
return <div/>
//we have a user!
return <div className="SplashPage">{userUrl} {currentUser}</div>
}
[原始答案]
编辑:对不起,我误解了你的问题,但会在这里留下我原来的答案,以防有人来寻找相关问题。
您收到 403 错误消息:
未提供身份验证凭据
您需要为您的请求添加某种授权(请参阅您的 django-rest-auth 配置/文档,了解它如何期望来自传入请求的授权)。
您可以手动为每个 api 调用进行设置,也可以通过 axios.interceptors.request.use() 进行设置,您需要在应用程序的某处导入和调用(例如在 app.js 或 index.js 中)
下面的例子:
- 使用 axios.interceptors
- 将授权令牌添加到 Authorization 标头
- 使用标准的“不记名令牌”
- 使用 firebase auth 演示通过异步检索令牌
(您的实际实施将取决于您的 api 的设置方式和您的授权流程)
addAuthHeader.js:
import axios from 'axios';
import * as firebase from 'firebase/app';
const apiUrl = 'http://localhost:8000/' // '/' if using the preferred http-proxy-middleware
export default addAuthHeader = () =>
//if firebase auth callback should be asyncasync
axios.interceptors.request.use(async (config) => {
if(config.url.startsWith(apiUrl)){
const token = await firebase.auth().currentUser.getIdToken(true)
config.headers.Authorization = `bearer ${token}`;
return config;
}
});
应用程序.js:
addAuthHeader()
推荐阅读
- installshield-2010 - (installshield)我想知道不管包程序中的文件如何运行
- javascript - 用javascript解析二进制点数据
- python - 嵌套类属性未被识别为 int
- r - 如何在 R 的 dplyr::mutate 函数中创建方程?
- javascript - 在行内使用 checkox 隐藏表格行
- ruby-on-rails - Ruby on Rails Bootstrap 下拉菜单在开发中工作,而不是 Heroku
- javascript - 在复选框限制后显示消息(多个实例)
- angular - 从角度 4 的任何地方访问全局文件
- sql - 如何在 SQL 的 select 语句中分配随机值?
- angular - 首次在 Google Cloud 上加载 Express/Angular 5 应用程序会在浏览器上引发“未找到”