最近接触了Python中的Django框架,建立了一个以Django为后端,vue 作为前端的web框架。在测试vue与Django前后端交互的时候遇到了获取request.body或者request.POST.data 获取为空的情况。记录一下自己的解决方法。
同源是指"协议+域名+端口"三者相同,只要三者之间有一项不同,就不算是同源。这里介绍的就是不同端口之间的数据交互问题。
简而言之,为了避免浏览器受到XSS,CSFR等攻击,不同源的服务进程之间无法直接进行数据交互。
要解决不同源问题,需要设置代理,使二者资源可以相互访问。我们可以选择在前端或者后端设置代理,最好是都设置代理。
在vue项目中的config/index.js文件加入以下代理来设置代理,如果没有此文件我们可以在根目录下建立一个vue.confg.js 文件来加入
module.exports = {
lintOnSave: false,
devServer: {
proxy: {
'/api': {
target: 'http://localhost:8000',
changeOrigin: true,
ws: true,
pathRewrite: {
'^/api': ''
}
}
}
}
}
最简单的一种方法是引入django-cors-headers(Django中)
pip install django-cors-headers
配置setting.py 文件,在里面加入下面的代码(前两项是添加到相应位置里)
INSTALLED_APPS = [
'corsheaders',
]
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
]
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_ALLOW_ALL = True
CORS_ORIGIN_WHITELIST = (
['http://127.0.0.1:*']
)
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',
)
下面为 views.py 中的文件,采用的是restful 风格,采用了 Django rest-framework 框架,没接触也问题不大,我们只需要拿到request 的数据就行
我们需要在函数之前加上 @csrf_exempt
class BookViewSet(ModelViewSet):
parser_classes = [JSONParser, FormParser]
"""视图集"""
queryset = models.BookInfo.objects.all()
serializer_class = BookInfoModelSerializer
# books/pk/createBook/
@action(methods=['post'], detail=True)
@csrf_exempt
def createBook(self, request, pk):
print(request.body)
serializer = UserInfoSerializer(data=json.loads(request.body.decode('utf8')))
if serializer.is_valid():
serializer.save() # 存入数据库
return JsonResponse({
'code': 2000,
'msg': '创建成功',
'data': 'algorithm'
})
else:
return JsonResponse({
'code': 2010,
'msg': '创建失败',
'data': 'algorithm'
})
我们现在使用postman发送post请求,里面实现的createBook方法就是用来获取发送到的post请求,获取post数据,并存入数据库。
打印的request.body如下
b'{\r\n "url" : "localhost",\r\n "name" : "\xe5\xb0\x8f\xe7\x8e\x8b\xe5\xad\x90"\r\n}'