Python的Django应用程序解决AJAX跨域访问问题的方法


Posted in Python onMay 31, 2016

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

<!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 src="http://libs.baidu.com/jquery/1.9.0/jquery.js"></script>
  <script>
    function showPersonInfo(){
      $.getJSON(
        'http://xxx/account/getuserinfo/',
        {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浏览器提示错误:

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提示的:

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请求数据:

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:

pip install django-cors-headers

在settings.py中增加:

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

...

MIDDLEWARE_CLASSES = (
  ...
  'corsheaders.middleware.CorsMiddleware',
  'django.middleware.common.CommonMiddleware',
  ...
)

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

Python 相关文章推荐
Python实现Linux命令xxd -i功能
Mar 06 Python
用pickle存储Python的原生对象方法
Apr 28 Python
在ubuntu16.04中将python3设置为默认的命令写法
Oct 31 Python
Django objects的查询结果转化为json的三种方式的方法
Nov 07 Python
python实现的MySQL增删改查操作实例小结
Dec 19 Python
在python中获取div的文本内容并和想定结果进行对比详解
Jan 02 Python
Python django框架应用中实现获取访问者ip地址示例
May 17 Python
Flask-WTF表单的使用方法
Jul 12 Python
浅谈django 模型类使用save()方法的好处与注意事项
Mar 28 Python
Python3操作读写CSV文件使用包过程解析
Apr 10 Python
Python就将所有的英文单词首字母变成大写
Feb 12 Python
Python 文字识别
May 11 Python
python语言使用技巧分享
May 31 #Python
Windows中安装使用Virtualenv来创建独立Python环境
May 31 #Python
Windows下Python使用Pandas模块操作Excel文件的教程
May 31 #Python
深入理解python中的浅拷贝和深拷贝
May 30 #Python
浅谈Python的文件类型
May 30 #Python
python中string模块各属性以及函数的用法介绍
May 30 #Python
Python 常用string函数详解
May 30 #Python
You might like
PHP教程 基本语法
2009/10/23 PHP
php自动加载的两种实现方法
2010/06/21 PHP
PHP简单选择排序算法实例
2015/01/26 PHP
php实现表单提交上传文件功能
2018/05/28 PHP
将HTML自动转为JS代码
2006/06/26 Javascript
JavaScript面向对象知识串结(读JavaScript高级程序设计(第三版))
2012/07/17 Javascript
页面图片浮动左右滑动效果的简单实现案例
2014/02/10 Javascript
使用documentElement正确取得当前可见区域的大小
2014/07/25 Javascript
jquery获得同源iframe内body下标签的值的方法
2014/09/25 Javascript
JS组件Bootstrap Table布局详解
2016/05/27 Javascript
Angularjs使用directive自定义指令实现attribute继承的方法详解
2016/08/05 Javascript
简单实现js无缝滚动效果
2017/02/05 Javascript
Angualrjs和bootstrap相结合实现数据表格table
2017/03/30 Javascript
原生JS+Canvas实现五子棋游戏
2020/05/28 Javascript
浅谈vue-router 路由传参的方法
2017/12/27 Javascript
vue单页面打包文件大?首次加载慢?nginx带你飞,从7.5M到1.3M蜕变过程(推荐)
2018/01/16 Javascript
解决webpack无法通过IP地址访问localhost的问题
2018/02/22 Javascript
JS实现“全选”和&quot;全不选&quot;功能代码实例
2020/02/06 Javascript
Nuxt默认模板、默认布局和自定义错误页面的实现
2020/05/11 Javascript
[01:34]传奇从这开始 2016国际邀请赛中国区预选赛震撼开启
2016/06/26 DOTA
[46:16]2018DOTA2亚洲邀请赛3月30日 小组赛B组 iG VS VP
2018/03/31 DOTA
Python实现的计数排序算法示例
2017/11/29 Python
Windows环境下python环境安装使用图文教程
2018/03/13 Python
python使用for循环计算0-100的整数的和方法
2019/02/01 Python
python适合人工智能的理由和优势
2019/06/28 Python
python join方法使用详解
2019/07/30 Python
Python替换NumPy数组中大于某个值的所有元素实例
2020/06/08 Python
基于Python编写一个计算器程序,实现简单的加减乘除和取余二元运算
2020/08/05 Python
法国综合购物网站:RueDuCommerce
2016/09/12 全球购物
美国知名的时尚购物网站:Anthropologie
2016/12/22 全球购物
毕业生机械建模求职信
2013/10/14 职场文书
技校学生个人职业生涯规划范文
2014/03/03 职场文书
高中生操行评语大全
2014/04/25 职场文书
小班下学期评语
2014/05/04 职场文书
2016年大学光棍节活动总结
2016/04/05 职场文书
virtualenv隔离Python环境的问题解析
2022/06/21 Python