zoukankan      html  css  js  c++  java
  • django处理跨域

      django处理Ajax跨域访问时使用javascript进行ajax访问的时候,出现如下错误

    这里写图片描述

    出错原因:javascript处于安全考虑,不允许跨域访问。下图是对跨域访问的解释:

    概念

      这里说的js跨域是指通过js或python在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(Django)的数据。只要协议、域名、端口有任何一个不同,都被当作是不同的域。

            跨域,简单来说就是 A 网站的 javascript 代码试图访问 B 网站,包括提交内容和获取内容。这显然是不安全的。为此,浏览器的鼻祖:网景(Netscape)公司提出了优秀的解决方案:著名的浏览器同源策略。现在所有支持JavaScript的浏览器都会使用这个策略。

           同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。同源策略,它是由Netscape提出的一个著名的安全策略。

           所谓同源是指,域名,协议,端口相同。当一个浏览器的两个tab页中分别打开来 百度和谷歌的页面,当浏览器的百度tab页执行一个脚本的时候会检查这个脚本是属于哪个页面的,即检查是否同源,只有和百度同源的脚本才会被执行。如果非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。

    解决办法

    1. 修改views.py文件

    修改views.py中对应API的实现函数,允许其他域通过Ajax请求数据:

    todo_list = [
        {"id": "1", "content": "吃饭"},
        {"id": "2", "content": "吃饭"},
    ]
    
    
    class Query(View):
        @staticmethod
        def get(request):
            response = JsonResponse(todo_list, safe=False)
            response["Access-Control-Allow-Origin"] = "*"   
            response["Access-Control-Allow-Methods"] = "POST, GET, OPTIONS"
            response["Access-Control-Max-Age"] = "1000"
            response["Access-Control-Allow-Headers"] = "*"
            return response
    
        @staticmethod
        def post(request):
            print(request.POST)
            return HttpResponse()
    • 简单请求 OR 非简单请求 
      条件: 
          1、请求方式:HEAD、GET、POST 
          2、请求头信息: 
              Accept Accept-Language 
              Content-Language 
              Last-Event-ID 
              Content-Type 对应的值是以下三个中的任意一个 
                  application/x-www-form-urlencoded 
                  multipart/form-data 
                  text/plain 
      注意:同时满足以上两个条件时,则是简单请求,否则为复杂请求 
      简单请求和非简单请求的区别? 
      简单请求:
          一次请求 
      非简单请求:
          两次请求,在发送数据之前会先发一次请求用于做“预检”,
          只有“预检”通过后才再发送一次请求用于数据传输。 
      关于“预检” 
          - 请求方式:OPTIONS 
          - “预检”其实做检查,检查如果通过则允许传输数据,检查不通过则不再发送真正想要发送的消息 
          - 如何“预检” 
              如果复杂请求是PUT等请求,则服务端需要设置允许某请求,否则“预检”不通过 
              Access-Control-Request-Method="PUT" 
              如果复杂请求设置了请求头,则服务端需要设置允许某请求头,否则“预检”不通过 
              Access-Control-Request-Headers="k1"
    • 基于cors实现的ajax请求:

      1、支持跨域的简单请求

        服务器设置响应头:Access-Control-Allow-Origin = '指定域名' 

        服务器设置响应头:Access-Control-Allow-Origin = '*'    # *:表示允许所有的请求

      2、复杂请求的请求头:

        由于复杂请求时,首先会发送“预检”请求,如果“预检”成功,则发送真实数据。   # 预检时可以发送空数据

        “预检”请求时,允许请求方式则需服务器设置响应头:Access-Control-Request-Method="PUT"    # 或其他复杂请求如DELETE

        “预检”请求时,允许请求头则需服务器设置响应头:Access-Control-Request-Headers="k1"     # ajax的header:{"k1":"v1"}

        “预检”缓存时间,服务器设置响应头:Access-Control-Max-Age=10   # 十秒内此请求再有请求过来时无需再发送options预检,直接发送复杂请求,减轻服务器压力

      3、跨域获取响应头

        默认获取到的所有响应头只有基本信息,如果想要获取自定义的响应头,则需要再服务器端设置Access-Control-Expose-Headers。

      4、跨域传输cookie

        在跨域请求中,默认情况下,HTTP Authentication信息,Cookie头以及用户的SSL证书无论在预检请求中或是在实际请求都是不会被发送。

        如果想要发送:

          浏览器端:XMLHttpRequest的withCredentials为true

          服务器端:Access-Control-Allow-Credentials为true

      注意:服务器端响应的 Access-Control-Allow-Origin 不能是通配符 


     

    2. 添加中间件 django-cors-headers

    GitHub地址: https://github.com/ottoyiu/django-cors-headers

    2.1. 安装

     pip install django-cors-headers

    2.2 添加app

    INSTALLED_APPS = (
        ...
        'corsheaders',
        ...
    )

    2.3 添加中间件

    MIDDLEWARE = [  # Or MIDDLEWARE_CLASSES on Django < 1.10
        ...
        'corsheaders.middleware.CorsMiddleware',
        'django.middleware.common.CommonMiddleware',
        ...
    ]

    2.4 配置允许跨站访问本站的地址

    CORS_ORIGIN_ALLOW_ALL = False
    CORS_ORIGIN_WHITELIST = ( 'localhost:63343', )

    # 默认值是全部:

    CORS_ORIGIN_WHITELIST = ()  # 或者定义允许的匹配路径正则表达式.

    CORS_ORIGIN_REGEX_WHITELIST = ('^(https?://)?(w+.)?>google.com$', )   # 默认值:

    CORS_ORIGIN_REGEX_WHITELIST = ()

    2.5 设置允许访问的方法

    CORS_ALLOW_METHODS = (
    'GET',
    'POST',
    'PUT',
    'PATCH',
    'DELETE',
    'OPTIONS'
    )

    2.6 设置允许的header:

    默认值:

    CORS_ALLOW_HEADERS = (
    'x-requested-with',
    'content-type',
    'accept',
    'origin',
    'authorization',
    'x-csrftoken'
    )
  • 相关阅读:
    第15周Leetcode记录
    《Redis深度历险》七(info指令和过期淘汰策略)
    第14周leetcode记录
    《Redis深度历险》六(事务+发布订阅+Stream)
    第13周LeetCode记录
    在Load average 高的情况下如何鉴别系统瓶颈
    Apache TraceEnable关闭与测试方法
    PHP 5.6 如何使用 CURL 上传文件
    转载-浅谈Ddos攻击攻击与防御
    基于SWOOLE的分布式SOCKET消息服务器架构
  • 原文地址:https://www.cnblogs.com/95lyj/p/9440169.html
Copyright © 2011-2022 走看看