So I am brand new to Javascript and React, I am trying to write a simple Login page that takes the login form data and sends a login request to a Django api I have created. The api should then return an HttpResponse with either 200 status or 401. I have enabled CORS in the api so they can communicate with each-other.
What I have discovered is that using correct login information the fetch is successful for the first attempt after the server is started, but consecutive login attempt always fail with a "TypeError: Failed to fetch" in the browsers console.
My Django api function:
# path 'login/'
def login_user(request):
login_attempt = json.loads(request.body.decode('utf-8'))
try:
user = models.User.objects.get(email=login_attempt['email'],
password=login_attempt['password'])
except models.User.DoesNotExist:
user = None
if user is not None:
return HttpResponse('Login Success', status=200)
return HttpResponse('Unauthorised', status=401)
Login.js:
class Login extends Component {
constructor(props) {
super(props);
this.state = {
email: '',
password: '',
};
this.handleEmailChange = this.handleEmailChange.bind(this);
this.handlePasswordChange = this.handlePasswordChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.handleResponse = this.handleResponse.bind(this);
}
handleEmailChange(event) {
this.setState({email: event.target.value})
}
handlePasswordChange(event) {
this.setState({password: event.target.value})
}
handleResponse(res) {
if (res.ok) {
alert('Login Successful!');
this.props.updateTheUser(this.state.email);
}
else if (res.status === 401) {
alert('Wrong Username or Password');
}
}
sendLoginRequest(data) {
fetch('http://localhost:8000/login/', {
method: 'POST',
headers: { 'Content-Type': 'application/json'},
body: data,
})
.then(this.handleResponse)
.catch(function(error) {
alert('Server error, please try again.');
console.error(error);
});
}
handleSubmit(event) {
const data = `{"email": "${this.state.email}", "password": "${this.state.password}"}`
this.sendLoginRequest(data);
}
User.js:
class User extends Component {
constructor(props) {
super(props);
this.state = {
email: '',
isLoggedIn: false
}
this.updateUser = this.updateUser.bind(this);
}
updateUser(email) {
console.log(`Entered User.updateUser, email: ${email}`);
this.setState({
email: email,
isLoggedIn: true
});
}
render() {
if (this.state.isLoggedIn) {
return <Dashboard/>
}
return <Login updateTheUser={this.updateUser}/>
}
}
Looking in the Network tab of the browser it shows the fetch status as Cancelled and can be seen in a screenshot here. I have also included screenshots of the requests details here and here.