前后端对接
前面简单说了前端和后端,然后根据我的理解谈谈前后端对接
前后端分离
什么是前后端分离呢?
前后端分离是目前一种非常流行的开发模式,它使项目的分工更加明确:
- 后端:负责处理、存储数据
- 前端:负责显示数据
简言之就是,前端和后端开发人员通过 接口 进行数据的交换。
对接中出现的问题
下面是我自己在对接时出现的问题,因为我前端相当于是提前写好的,所以我在对接起来问题很多,不灵活
跨域请求问题
导致跨域问题的主要原因是,一个url中,协议,域名,端口号其中一个与当前页面不同(同源策略)
简单来说,就是我们在项目中,要使用其他项目中的资源就会造成跨域,也就是说只能访问本项目中的东西。
例如,一个html获取利用同项目的资源,能正常使用,但是同样的html获取利用另一个项目的资源,反而会产生跨域问题。再如变量的作用域,只要你们超过各自作用范围,就会出现问题。
跨域问题 一
常见形式,我又复现了一下:
代码语言:javascript复制Access to XMLHttpRequest at ‘http://127.0.0.1:8000/’ from origin ‘http://localhost:8080’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.
含有“Access-Control-Allow-Origin”都是跨域问题的一种,就像上面的这个,解决方案如下:
中间件方法解决
这时,可以写一个中间件来解决跨域问题:(当然不是我写的,一位大佬zkg,非常感谢!!!)
(这是它的博客地址:赵苦瓜のBlog )
代码语言:javascript复制"""
@FILE_NAME : Middleware
-*- coding : utf-8 -*-
@Author : ZhaoKugua
@Time : 2021/7/27
"""
class TestMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
response = self.get_response(request)
response["Access-Control-Allow-Headers"] = "*"
response["Access-Control-Allow-Origin"] = "*"
response["Access-Control-Allow-Methods"] = "*"
response["Access-Control-Allow-Credentials"] = "*"
return response
将这个这个文件放于Django项目的APP应用目录下,然后在settings.py中进行设置:
代码语言:javascript复制MIDDLEWARE = [
...后面加入下面这句,引用一下
'APP.middle.TestMiddleware' #跨域的中间件
]
根据我的问题我改动了一下,
response["Access-Control-Allow-Methods"] = "*"
是允许所有的请求方法,我后面会再说
自行验证跨域:
打开浏览器控制台,在里面输入以下代码,并修改链接为你要测试的链接
代码语言:javascript复制var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://127.0.0.1:8000/viewuser/');#这里是你写好的接口
xhr.send(null);
xhr.onload = function(e) {
var xhr = e.target;
console.log(xhr.responseText);
}
你会发现,跨域问题解决啦~
跨域问题 二
还有一种跨域问题大概意思是:
前端在post请求前会自动发送options请求,来测试要传参接口的安全性,而往往会被后端拦截而报错
解决方法:
1.在中间件里添加response[“Access-Control-Allow-Methods”] = “*”,很好理解
2.修改具体的views视图函数:(这是我的例子)
代码语言:javascript复制#注册 (用户的手机号即为注册的id)
@csrf_exempt
def allregist(request):
if request.method=='OPTIONS':
result_dict={
'code':200,
'message':'options success'
}
return JsonResponse(result_dict, json_dumps_params={'ensure_ascii': False})
if request.method == "POST":
body = request.body.decode('utf8')
info = json.loads(body)
password = info['password']
name = info['userName']
phone =info['phone'] # uid和phone相同,留一个,调
id = phone
status = 'True'
image = ''
user_end = User.objects.filter(uid=id)
if user_end: #表明该用户注册过
result = {
'code': 404,
'message': '该手机号已经注册过了!',
'dict': []
}
return JsonResponse(result, json_dumps_params={'ensure_ascii': False})
else:
user = User.objects.create(uid=id, password=password, name=name, phone=phone, status=status, image=image)
user.save()
result = {
'code': 200,
'message': '注册成功!',
'dict': []
}
return JsonResponse(result, json_dumps_params={'ensure_ascii': False})
这里主要涉及两个点:
- @csrf_exempt
- def allregist(request): if request.method==’OPTIONS’: result_dict={ ‘code’:200, ‘message’:’options success’ } return JsonResponse(result_dict, json_dumps_params={‘ensure_ascii’: False}) 如果前端options请求,那么返回200,即请求成功,那么就不会报错啦~
文件上传
我以图片为例,具体实现方式:
前端:
通过 Form表单 将图片文件以参数形式post给后端
后端:
1.在settings.py中进行设置:(前一篇博客也提到过)
代码语言:javascript复制STATIC_URL = 'static/'
#STATIC_ROOT = os.path.join(BASE_DIR, 'collected_static')
#关于图片上传的路径配置
MEDIA_URL = '/media/'
MEDIA_ROOT=os.path.join(BASE_DIR, 'media')
这样对文件上传路径进行配置
2.在models.py中:
代码语言:javascript复制#新建的模型中:
image = models.ImageField(upload_to='photos',null=True,default='123.jpg') #用户上传的图片,括号里参数,
第一个代表传到photos文件夹中,第二个是可以为空,
第三个是默认值为123.jpg
注意:上传到photos文件夹里,具体是指,项目的media目录下的photos文件夹
3.views.py进行图片上传视图函数的编写(写好后将路径添加至urls.py中)
同样以我的为例:
代码语言:javascript复制#用户上传图片
@csrf_exempt
def UpLoadInfo(request):
if request.method == 'OPTIONS':
result_dict = {
'code': 200,
'message': 'options success'
}
return JsonResponse(result_dict, json_dumps_params={'ensure_ascii': False})
if request.method == "POST":
id = request.POST.get('id')
print(id)
photo = request.FILES.get('photo')
result = User.objects.get(uid=id)
result.image.delete()
result.image = photo
result.save()
result_dict = {
'code': 200,
'message': 'Upload success!',
}
return JsonResponse(result_dict, json_dumps_params={'ensure_ascii': False})
else:
result_dict = {
'code': 404,
'message': 'Upload failed',
}
return JsonResponse(result_dict, json_dumps_params={'ensure_ascii': False})
开发技巧
后端开发有个小技巧就是:
你所给前端调用的接口,应在postman提前测试,
这个软件很方便的,还可以自定义更改请求方式(POST,GET等等),同时还可以自定义上传参数,用过的人都说好~
网址我也放在这里了,Postman API Platform
进行接口测试真的很不错
总结
上面便是我耗费两个多星期完成的一个网站,也是属于那种能跑就行的状态,bug一堆,
在这个过程中,我经历了各种折磨,但是在经过各种探索解决问题之后的那种愉悦感真的很好!
而做这个项目的初衷,可能就是为了了却我的某个心愿罢了,但是毕竟还年轻,敢于尝试,敢于试错,就像我之前听到的一句话:
——“我要一点一点的走,哪怕走得很慢。”
那么,感触颇多的我就说到这里吧,后续分享一下如何在5分钟之内搭建一个精美实用的个人博客,我没吹牛 -_- 新年愿望,每天进步天天开心hhh~