最近在写项目,一直在钻研前端框架React
因为本人之前写项目都是用Django
导致前后端不分离,当然,写的也很舒服,最近打算写一个新的项目,将前后端分离:
React
+ Antd
+ React-Router
+ axios
+ Django
前端用组件化的React
前端框架,UI界面用非常好用的基于React
写的Antd
蚂蚁金服的项目
后端是Python
web框架Django
这样实现了 Django
只作为接口,路由跳转,由React
控制
由于之前ajax
异步用的是 JQuery
第一次用axios
导致踩了很多坑,接下来我把出现的问题给大家列出来以及解决办法:
webpack
开启项目和后端端口不一样 会出现跨域问题axios
会请求两次:第一次options
会验证一些上传的东西- 传给后端的数据格式是不一样的,并不是传统的
application/x-www-form-urlencoded
而是Request Payload
形式传到后段的
问题一:
跨域问题,本地环境测试的话 就需要在``Django``做调整,如果是线上的话,直接在Nginx或者Apache添加头部信息就好,Django有一个专门解决跨域的包,这个非常的好
pip install django-cors-headers
配置settings.py文件
INSTALLED_APPS = [
...
'corsheaders', #必须添加
...
]
MIDDLEWARE_CLASSES = (
...
'corsheaders.middleware.CorsMiddleware', #这个在common上面
'django.middleware.common.CommonMiddleware',
...
)
#跨域增加忽略
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_ALLOW_ALL = True
CORS_ORIGIN_WHITELIST = (
'*'
)
CORS_ALLOW_METHODS = (
'DELETE',
'GET',
'OPTIONS',
'PATCH',
'POST',
'PUT',
'VIEW',
)
CORS_ALLOW_HEADERS = (
'XMLHttpRequest',
'X_FILENAME',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-requested-with',
'Pragma',
)
问题二:
第二个问题导致了 请求两次,第一次请求是``options``第二次才是 post,我们更改一下传输数据结构,引入axios自带的QS转换一下
import Qs from 'qs'
var formData = this.props.form.getFieldsValue();
console.log(formData)
axios.post('http://localhost:8000/api/v1/register/',
Qs.stringify( { #在这里将post数据转换为query
username: formData.username,
password: formData.password,
repeat_password: formData.repeat_password
}),
)
.then((response) => {
if (response.data.result.data.code == 200) {
message.success('注册成功!')
this.setModalVisible(false)
} else {
message.error('输入有误!!')
}
})
.catch((response) => {
console.log(response)
})
问题三:
虽然现在正常了,后端也能看到前端post过去的数据了,但是我发现数据格式还是有问题,他并不是传统的x-www,我们需要在axios header头里面更改数据类型
{headers:{'Content-Type':'application/x-www-form-urlencoded'}}
完整的请求如下:
axios.post('http://localhost:8000/api/v1/register/',
Qs.stringify( {
username: formData.username,
password: formData.password,
repeat_password: formData.repeat_password
}),
{headers:{'Content-Type':'application/x-www-form-urlencoded'}}
)
.then((response) => {
if (response.data.result.data.code == 200) {
message.success('注册成功!')
this.setModalVisible(false)
} else {
message.error('输入有误!!')
}
})
.catch((response) => {
console.log(response)
})
}
个人博客: https://igolang.cn