在基于React的前端使用axios与基于Django rest框架的后端进行通讯时,我们遇到了一个非常奇怪的情况。
在登录预检OPTIONS请求时,axios发送了请求(如预期的那样),但是后端第一次接收到该请求时,该请求似乎格式错误,因此导致401。 但是,如果我重试,或者甚至使用浏览器开发工具重播完全相同的请求,则后端会接受OPTIONS请求,并且一切都会按预期进行。我们可以始终如一地重现这一点。
Django开发服务器日志如下:
第一个请求
[23/Jan/2019 15:43:42] "{}OPTIONS /backend/api/auth/login/ HTTP/1.1" 401
后续重试
[23/Jan/2019 15:43:52] "OPTIONS /backend/api/auth/login/ HTTP/1.1" 200 0
[23/Jan/2019 15:43:52] "POST /backend/api/auth/login/ HTTP/1.1" 200 76
如您所见,在请求方法中添加了花括号,这意味着该请求不被视为OPTIONS请求,因此返回401。
Django视图
class LoginView(KnoxLoginView):
authentication_classes = [BasicAuthentication]
# urls.py (extract)
path('auth/login/', LoginView.as_view(), name='knox_login'),
Axios请求
axios.post('/backend/api/auth/login/', {}, {
headers: {
'Authorization': 'Basic ' + window.btoa(creds.username + ":" + creds.password)
}
}).then((response) => {
dispatch({type: 'SIGNIN_SUCCESS', response})
}).catch((err) => {
dispatch({type: 'SIGNIN_ERROR', err})
})
某些软件包的版本信息
Django==2.1.4
django-cors-headers==2.4.0
django-debug-toolbar==1.11
django-extensions==2.1.4
django-rest-knox==3.6.0
django-rest-passwordreset==0.9.7
djangorestframework==3.9.0
axios@0.18.0