zoukankan      html  css  js  c++  java
  • DRF--跨域

    跨域

    跨域是因为浏览器的同源策略导致的,也就是说浏览器会阻止非同源的请求。那什么是非同源呢?既域名不同,端口不同,都属于非同源的。比如我们用vue写了个前端页面,端口为8081,Django写了个后台,端口为8000,前端往后台提交数据,后台返回数据会被浏览器拦截,因为端口不同。这就是跨域。

    浏览器只阻止表单以及ajax请求,并不会阻止src请求。所以我们得CDN,图片等src都可以发送。

    跨域请求分为两种,一种是简单请求,一种是复杂请求。

    简单请求

    HTTP方法是下列方法之一

    •   HEAD、GET、POST

    HTTP头信息不超过以下几种字段

    •   Accept,Accept-Language、Content-Language、Last-Event-ID
    •   Content-Type只能是下列类型中的一个
      •  application/x-www-from-urlencode
      •  multpart/from-data
      •  text/plain

    复杂请求 

    任何一个不满足上述要求的情求,都认为是复杂请求

    复杂请求会先发出一个预请求,我们也叫预检,OPTIONS请求

    比如发送了一个post请求,Content-Type为application/json。就是复杂请求

    解决跨域(方法一)

    在很久很久以前,人们解决跨域是通过JSONP来实现的。jsonp的实现原理是根据浏览器不阻止src请求入手来实现的。

    JSONP解决跨域只能发送get请求,并且实现起来需要前后端交互比较多,所以现在已经不使用了。

    现在常用的解决跨域的方法是添加响应头,在response里添加响应头告诉浏览器不用对请求进行拦截。

    因为跨域是浏览器的同源策略导致的,我们前端发送的数据是提交到后端的,后段也返回了数据,只是浏览器没有渲染。我们都知道Django的中间件会在视图之前和视图之后去执行,因为数据是返回了得,我们可以写个中间件,写个process_response方法,在返回响应之前执行,然后返回给浏览器就可以了

    from django.utils.deprecation import MiddlewareMixin
    
    
    class MyCors(MiddlewareMixin):
        def process_response(self, request, response):
            response["Access-Control-Allow-Origin"] = "*"
            if request.method == "OPTIONS":
                # 复杂请求会先发预检
                response["Access-Control-Allow-Headers"] = "Content-Type"
                # 对其他方法的请求也不做拦截
                response["Access-Control-Allow-Methods"] = "DELETE, PUT, POST"
            return response

    解决跨域(方法二)

    使用第三方库解决跨域的问题

    1.安装第三方库django-cors-headers

    pip install django-cors-headers

    2.django-cors-headers是一个app,所以需要我们在settings.py里的app里注册 corsheaders,尽量放在前面

    3.添加中间件,需要放在 'django.middleware.common.CommonMiddleware' 中间件之前

    'corsheaders.middleware.CorsMiddleware',

     4.添加白名单

    CORS_ALLOW_CREDENTIALS = True  # 允许跨域时携带Cookie,默认为False
    CORS_ORIGIN_ALLOW_ALL = True  # 所有ip都可以访问后端接口
    # CORS_ORIGIN_WHITELIST = ["http://127.0.0.1:8080",["http://192.168.10.1:8080"]  # 指定能够访问后端接口的ip或域名列表
    
    # 允许访问的请求方法
    CORS_ALLOW_METHODS = (
        'DELETE',
        'GET',
        'OPTIONS',
        'PATCH',
        'POST',
        'PUT',
        'VIEW',
    )
    
    # 允许的headers
    CORS_ALLOW_HEADERS = (
        'accept',
        'accept-encoding',
        'authorization',
        'content-type',
        'dnt',
        'origin',
        'user-agent',
        'x-csrftoken',
        'x-requested-with',
    )

    这样也可以解决跨域的问题,建议使用这种方法解决跨域

  • 相关阅读:
    Hibernate课程 初探一对多映射3-1 单向多对一简介
    Hibernate课程 初探一对多映射2-8 set元素属性
    Hibernate课程 初探一对多映射2-7 测试-修改和删除学生信息
    vue.js源码学习分享(二)
    vue.js源码学习分享(一)
    用百度地图做了一个输入地址查询经纬度的小例子
    今天碰到的400错误
    ajax同步
    json键的不能像值一样拼写的问题
    日期格式化
  • 原文地址:https://www.cnblogs.com/zouzou-busy/p/11601002.html
Copyright © 2011-2022 走看看