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的Asyncore异步Socket模块及实现端口转发的例子
Jun 14 Python
python交互式图形编程实例(三)
Nov 17 Python
python查询mysql,返回json的实例
Mar 26 Python
python自动登录12306并自动点击验证码完成登录的实现源代码
Apr 25 Python
关于Python的一些学习总结
May 25 Python
Python实现的读写json文件功能示例
Jun 05 Python
python实现飞机大战微信小游戏
Mar 21 Python
Python中断多重循环的几种方式详解
Feb 10 Python
Python3读写ini配置文件的示例
Nov 06 Python
python 合并多个excel中同名的sheet
Jan 22 Python
Python 解决空列表.append() 输出为None的问题
May 23 Python
python实现简单聊天功能
Jul 07 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 is_file()和is_dir()用于遍历目录时用法注意事项
2010/03/02 PHP
php学习笔记 面向对象中[接口]与[多态性]的应用
2011/06/16 PHP
模板引擎正则表达式调试小技巧
2011/07/20 PHP
Apache服务器无法使用的解决方法
2013/05/08 PHP
Yii2分页的使用及其扩展方法详解
2016/05/23 PHP
PHP版单点登陆实现方案的实例
2016/11/17 PHP
php如何比较两个浮点数是否相等详解
2019/02/12 PHP
php 根据URL下载远程图片、压缩包、pdf等文件到本地
2019/07/26 PHP
javascript下操作css的float属性的特殊写法
2007/08/22 Javascript
JavaScript 动态改变图片大小
2009/06/11 Javascript
js打印纸函数代码(递归)
2010/06/18 Javascript
JS截取url中问号后面参数的值信息
2014/04/29 Javascript
简单易用的倒计时js代码
2014/08/04 Javascript
js实现文章文字大小字号功能完整实例
2014/11/01 Javascript
jQuery实现在下拉列表选择时获取json数据的方法
2015/04/16 Javascript
JavaScript中的函数嵌套使用
2015/06/04 Javascript
JS截取与分割字符串常用技巧总结
2015/11/10 Javascript
javascript:void(0)点击登录没反应怎么解决
2015/11/13 Javascript
jQuery实现textarea自动增长宽高的方法
2015/12/18 Javascript
微信小程序 scroll-view隐藏滚动条详解
2017/01/16 Javascript
Vue.js 插件开发详解
2017/03/29 Javascript
[01:48:04]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Elephant BO3 第一场 2月7日
2021/03/11 DOTA
wxpython中Textctrl回车事件无效的解决方法
2016/07/21 Python
Python基于生成器迭代实现的八皇后问题示例
2018/05/23 Python
Python爬虫实现验证码登录代码实例
2019/05/10 Python
Python实现操纵控制windows注册表的方法分析
2019/05/24 Python
python实现键盘输入的实操方法
2019/07/16 Python
Python DataFrame一列拆成多列以及一行拆成多行
2019/08/06 Python
Python中IP地址处理IPy模块的方法
2019/08/16 Python
Python基础之列表常见操作经典实例详解
2020/02/26 Python
python matplotlib包图像配色方案分享
2020/03/14 Python
LN-CC日本:高端男装和女装的奢侈时尚目的地
2019/09/01 全球购物
企业元宵节主持词
2014/03/25 职场文书
贷款委托书怎么写
2014/08/02 职场文书
邀请书模板
2015/02/02 职场文书
图文详解matlab原始处理图像几何变换
2021/07/09 Python