• Django跨域请求问题的解决方法示例


      针对Django中在编写供AJAX调用的API时碰到的跨域问题,我们来总结下Python的Django应用程序解决AJAX跨域访问问题的方法,其中使用GitHub上开源分享的django-cors-headers尤其推荐

    引子
      使用Django在服务器端写了一个API,返回一个JSON数据。使用Ajax调用该API:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    <!DOCTYPE HTML>
    <html>
    <head>
      <meta charset="utf-8">
      <meta name="viewport" content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0"/>
      <title>test</title>
    </head>
    <body>
    <button onclick="showPersonInfo()">点我获取数据</button>
    </body>
      <script>
        function showPersonInfo(){
          $.getJSON(
            {username: "abc"},
            function(json) {
              var html='<br>'+'用户名:'+json.username+'<br>'+'姓:'+json.first_name+'<br>'+'名:'+json.last_name+'<br>'+'邮箱'+json.email;   
              document.write(html);
            }
          )
        }
      </script>
    </html>

      但是,Chrome浏览器提示错误:

    1
    No 'Access-Control-Allow-Origin' header is present on the requested resource.

    经过一番Google发现这个问题是——CORS导致的。

    什么是CORS?
      CORS(跨域资源共享,Cross-Origin Resource Sharing)是一种跨域访问的机制,可以让Ajax实现跨域访问。
      其实,在服务器的response header中,加入“Access-Control-Allow-Origin: *”即可支持CORS,非常的简单,apache/nginx等怎么配置,见参考文档。
      举个例子:

    • API部署在DomainA上;
    • Ajax文件部署在DomainB上,Ajax文件会向API发送请求,返回数据;
    • 用户通过DomainC访问DomainB的Ajax文件,请求数据

      以上过程就发生了跨域访问。如果直接使用Ajax来请求就会失败,就像Chrome提示的:

    1
    No 'Access-Control-Allow-Origin' header is present on the requested resource.

    如何解决Ajax跨域访问问题?
      解决跨域问题,有两个方法:1.使用jsonp 2.使CORS生效
      使用jsonp方法,需要让服务器端放回jsonp格式的response,如Django可以加jsonp相关的decorator,如:https://coderwall.com/p/k8vb_a/returning-json-jsonp-from-a-django-view-with-a-little-decorator-help由于我不太喜欢这种方式,所以这里略过了,可看后面的参考资料。
      使用CORS:这个用起来比较方便,现在大多数浏览器都支持了,且我web服务器完全开放给别人调用,所以比较推荐CORS。
    1.使用JSONP
      使用Ajax获取json数据时,存在跨域的限制。不过,在Web页面上调用js的script脚本文件时却不受跨域的影响,JSONP就是利用这个来实现跨域的传输。因此,我们需要将Ajax调用中的dataType从JSON改为JSONP(相应的API也需要支持JSONP)格式。
      JSONP只能用于GET请求。

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

    1
    2
    3
    4
    5
    6
    7
    def myview(_request):
      response = HttpResponse(json.dumps({"key": "value", "key2": "value"}))
      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

    3.安装django-cors-headers
      这里还有一各发现!在Django中,有人开发了CORS-header的middleware,只在settings.py中做一些简单的配置即可,见:https://github.com/ottoyiu/django-cors-headers/现在用起来服务器端完全开放,开启CORS,没有跨域烦恼,真爽!~
      安装django-cors-headers:

    1
    pip install django-cors-headers

      在settings.py中增加:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    INSTALLED_APPS = (
      ...
      'corsheaders',
      ...
    )
     
    ...
     
    MIDDLEWARE_CLASSES = (
      ...
      'corsheaders.middleware.CorsMiddleware',
      'django.middleware.common.CommonMiddleware',
      ...
    )

      可以配置允许跨域访问的白名单或者直接设置为允许所有的跨域访问,具体的配置可以看看他们的github页说明。

  • 相关阅读:
    关于数据库索引,必须掌握的知识点
    Java基础知识面试题(最详细版)
    基于WinForm制作的用户名密码存储器
    DataGridView点击列名自动排序
    WebRequest.Create(url)无效的URI:无效端口指定的URL时
    knockout 数据绑定,同一个页面table位置加载两个不同的表格数据
    pipeline管道初体验
    Socket,长连接,消息推送,消息提醒,未读消息提醒,消息通知,未读消息通知
    搭建SVN服务器
    C#解决jsonp跨域问题jsonp跨域配置
  • 原文地址:https://www.cnblogs.com/wdbgqq/p/10029145.html
Copyright © 2020-2023  润新知