项目搭建历程-Part III

汐语 2023-1-28 1,076 1/28
项目搭建历程-Part III

前后端对接

前面简单说了前端和后端,然后根据我的理解谈谈前后端对接

前后端分离

什么是前后端分离呢?

前后端分离是目前一种非常流行的开发模式,它使项目的分工更加明确:

  • 后端:负责处理、存储数据
  • 前端:负责显示数据

简言之就是,前端和后端开发人员通过 接口 进行数据的交换。

项目搭建历程-Part III

对接中出现的问题

下面是我自己在对接时出现的问题,因为我前端相当于是提前写好的,所以我在对接起来问题很多,不灵活

跨域请求问题

导致跨域问题的主要原因是,一个url中,协议,域名,端口号其中一个与当前页面不同(同源策略)

简单来说,就是我们在项目中,要使用其他项目中的资源就会造成跨域,也就是说只能访问本项目中的东西。

例如,一个html获取利用同项目的资源,能正常使用,但是同样的html获取利用另一个项目的资源,反而会产生跨域问题。再如变量的作用域,只要你们超过各自作用范围,就会出现问题。

跨域问题 一

常见形式,我又复现了一下:

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 )

"""
@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中进行设置:

MIDDLEWARE = [
    ...后面加入下面这句,引用一下
    'APP.middle.TestMiddleware' #跨域的中间件
]

根据我的问题我改动了一下,

response["Access-Control-Allow-Methods"] = "*" 是允许所有的请求方法,我后面会再说

自行验证跨域

打开浏览器控制台,在里面输入以下代码,并修改链接为你要测试的链接

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视图函数:(这是我的例子)

#注册 (用户的手机号即为注册的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})

这里主要涉及两个点:

  1. @csrf_exempt
  2. 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中进行设置:(前一篇博客也提到过)

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中:

#新建的模型中:
​
image = models.ImageField(upload_to='photos',null=True,default='123.jpg') #用户上传的图片,括号里参数,
第一个代表传到photos文件夹中,第二个是可以为空,
第三个是默认值为123.jpg

注意:上传到photos文件夹里,具体是指,项目的media目录下的photos文件夹

3.views.py进行图片上传视图函数的编写(写好后将路径添加至urls.py中)

同样以我的为例:

#用户上传图片
@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~

- THE END -

汐语

3月23日20:57

最后修改:2023年3月23日
0

非特殊说明,本博所有文章均为博主原创。

共有 2 条评论

  1. 汐语要好好学习

    本站迁移进度 2/3
    时间 2月2日 1:00

  2. 汐语

    汐语博主

    博客迁移第三篇打卡~