017---Django的中间件解决跨域

跨域
  • 跨域是什么?
    浏览器从一个域名的网页去请求另一个域名的资源的时候,如果不同源、请求的响应结果就会被浏览器的同源策略所拦截
  • 同源策略是什么?
    同源:协议 + 域名 + 端口
    特点:阻止ajax请求、不阻止src请求
    所以不同源就会被拦截
  • 解决方式
    • JSONP

      • 新建项目CORS
      # urls.py
      
      from django.contrib import admin
      from django.urls import path
      from app01 import views
      
      urlpatterns = [
          path('admin/', admin.site.urls),
          path('index/',views.index),
          path('service/',views.CORSView.as_view()),
      ]
      
      # views.py
      from django.shortcuts import render, HttpResponse
      from django.views import View
      
      def index(request):
          return render(request,'index.html')
      
      
      class CORSView(View):
      
          def get(self,request):
              return HttpResponse('get--ok')
      
      • 新建html文件,写js,发送请求

      • 单独运行html文件和在走index视图再发生请求,会有两个结果,一个被拦截。一个没拦截。

      • 怎么解决呢?可以根据src请求不拦截的特点。在点击获取服务器数据的按钮的时候生成一个script标签,属性src就是我们要请求的url,可以携带一个回调函数过去。服务器返回数据之后执行回调函数。获取之后再删除script标签。

    • CORS添加响应头

      • 先了解两个概念:简单请求和复杂请求
        • 简单请求:
          1. HTTP方法(之一):HEAD, GET,POST
          2. HTTP头信息(不得超出):Accept, Accept-Language, Content-Language, Last-Event-ID
          3. Content-Type(之一):application/x-www-from-urlencoded multipart/form-data text/plain
        • 复杂请求:
          1. 先发送预检请求 OPTIONS
      • 这个比jsonp简单多了。只要我们后端写个中间件。允许通过的域名和方法即可
      # views.py
      from django.shortcuts import render, HttpResponse
      from django.views import View
      from django.views.decorators.csrf import csrf_exempt
      from django.utils.decorators import method_decorator
      
      def index(request):
          return render(request, 'index.html')
      
      
      @method_decorator(csrf_exempt, name='dispatch')
      class CORSView(View):
      
          def get(self, request):
              # func = request.GET.get('callback')
              # print(func)
              # data = 'get--ok'
              # return HttpResponse("%s('%s')" % (func, data))
      
              return HttpResponse('get--ok')
      
          def post(self, request):
              return HttpResponse('post--ok')
      
          def put(self, request):
              return HttpResponse('put--ok')
      
      # app01\middlewares\cors.py
      
      from django.utils.deprecation import MiddlewareMixin
      class MyCors(MiddlewareMixin):
          """
          跨域中间件
          """
          def process_response(self, request, response):
              response['Access-Control-Allow-Origin'] = '*'
              # 如果是简单请求这样即可,但是我们一般方送json格式的数据,还有可能会有其他method,所有还要进一步判断
              if request.method == 'OPTIONS':
                  # 复杂请求会先发预检
                  response["Access-Control-Allow-Headers"] = "Content-Type"
                  response["Access-Control-Allow-Methods"] = "PUT,PATCH,DELETE"
              return response
      
      • 单独打开我们的html文件发送ajax请求。get、post、put都可以获取数据

posted @ 2019-01-24 15:19  爬呀爬Xjm  阅读(283)  评论(0编辑  收藏  举报