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 相关文章推荐
如何利用Fabric自动化你的任务
Oct 20 Python
python虚拟环境的安装配置图文教程
Oct 20 Python
python编程线性回归代码示例
Dec 07 Python
Python 错误和异常代码详解
Jan 29 Python
python的格式化输出(format,%)实例详解
Jun 01 Python
解决pandas使用read_csv()读取文件遇到的问题
Jun 15 Python
python取数作为临时极大值(极小值)的方法
Oct 15 Python
对Python中小整数对象池和大整数对象池的使用详解
Jul 09 Python
python中单下划线(_)和双下划线(__)的特殊用法
Aug 29 Python
python解析yaml文件过程详解
Aug 30 Python
python regex库实例用法总结
Jan 03 Python
python实现杨辉三角的几种方法代码实例
Mar 02 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中的integer类型使用分析
2010/07/27 PHP
php mail to 配置详解
2014/01/16 PHP
ThinkPHP5实现作业管理系统中处理学生未交作业与已交作业信息的方法
2016/11/12 PHP
CI框架常用经典操作类总结(路由,伪静态,分页,session,验证码等)
2016/11/21 PHP
php 自定义函数实现将数据 以excel 表格形式导出示例
2019/11/13 PHP
基于jQuery的固定表格头部的代码(IE6,7,8测试通过)
2010/05/18 Javascript
jQuery实现动态添加和删除一个div
2015/08/12 Javascript
初识简单却不失优雅的Vue.js
2016/09/12 Javascript
Bootstrap字体图标无法正常显示的解决方法
2016/10/08 Javascript
javascript 动态脚本添加的简单方法
2016/10/11 Javascript
JS冒泡事件与事件捕获实例详解
2016/11/25 Javascript
js实现九宫格抽奖
2020/03/19 Javascript
详解JavaScript的this指向和绑定
2020/09/08 Javascript
keep-alive保持组件状态的方法
2020/12/02 Javascript
js实现简单商品筛选功能
2021/02/02 Javascript
[48:53]2014 DOTA2华西杯精英邀请赛 5 25 LGD VS VG第一场
2014/05/26 DOTA
小小聊天室Python代码实现
2016/08/17 Python
Python实现计算两个时间之间相差天数的方法
2017/05/10 Python
python使用fork实现守护进程的方法
2017/11/16 Python
Python与人工神经网络:使用神经网络识别手写图像介绍
2017/12/19 Python
Python读取Word(.docx)正文信息的方法
2018/03/15 Python
python 通过SSHTunnelForwarder隧道连接redis的方法
2019/02/19 Python
浅谈Python反射 &amp; 单例模式
2019/03/21 Python
Python何时应该使用Lambda函数
2019/07/02 Python
django框架使用方法详解
2019/07/18 Python
python迭代器常见用法实例分析
2019/11/22 Python
Python单链表原理与实现方法详解
2020/02/22 Python
Python txt文件如何转换成字典
2020/11/03 Python
详解Canvas 实现炫丽的粒子运动效果(粒子生成文字)
2018/02/01 HTML / CSS
优衣库美国官网:UNIQLO美国
2018/04/14 全球购物
业务员自荐信范文
2014/04/20 职场文书
工程材料采购方案
2014/05/18 职场文书
春节超市活动方案
2014/08/14 职场文书
出资证明书范本(标准版)
2014/09/24 职场文书
事业单位工作人员年度考核个人总结
2015/02/12 职场文书
使用python如何删除同一文件夹下相似的图片
2021/05/07 Python