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实用日期时间处理方法汇总
May 09 Python
Python编程pygame模块实现移动的小车示例代码
Jan 03 Python
详解通过API管理或定制开发ECS实例
Sep 30 Python
浅谈Pandas Series 和 Numpy array中的相同点
Jun 28 Python
Python GUI学习之登录系统界面篇
Aug 21 Python
python二维键值数组生成转json的例子
Dec 06 Python
如何通过Django使用本地css/js文件
Jan 20 Python
Python @property装饰器原理解析
Jan 22 Python
python实现图片素描效果
Sep 26 Python
python代码实现图书管理系统
Nov 30 Python
详解win10下pytorch-gpu安装以及CUDA详细安装过程
Jan 28 Python
教你怎么用Python处理excel实现自动化办公
Apr 30 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 无法加载mysql的module的时候的配置的解决方案引发的思考
2012/01/27 PHP
php的4种常见运行方式
2015/03/20 PHP
PHP memcache在微信公众平台的应用方法示例
2017/09/13 PHP
Aster vs Newbee BO5 第三场2.19
2021/03/10 DOTA
JavaScript的面向对象方法以及差别
2008/03/31 Javascript
jQuery Ajax之$.get()方法和$.post()方法
2009/10/12 Javascript
从零开始学习jQuery (十) jQueryUI常用功能实战
2011/02/23 Javascript
js中的string.format函数代码
2020/08/11 Javascript
用JavaScript获取DOM元素位置和尺寸大小的方法
2013/04/12 Javascript
jquery拖动插件(jquery.drag)使用介绍
2013/06/18 Javascript
javascript快速排序算法详解
2014/09/17 Javascript
Javascript核心读书有感之词法结构
2015/02/01 Javascript
JavaScript实现列表分页功能特效
2015/05/15 Javascript
一种新的javascript对象创建方式Object.create()
2015/12/28 Javascript
基于Node.js的强大爬虫 能直接发布抓取的文章哦
2016/01/10 Javascript
jquery实现全选、不选、反选的两种方法
2016/09/06 Javascript
JS冒泡事件与事件捕获实例详解
2016/11/25 Javascript
Javascript highcharts 饼图显示数量和百分比实例代码
2016/12/06 Javascript
JS实现简易留言板特效
2019/12/23 Javascript
分享一款超好用的JavaScript 打包压缩工具
2020/04/26 Javascript
javascript实现打砖块小游戏(附完整源码)
2020/09/18 Javascript
使用Python脚本和ADB命令实现卸载App
2017/02/10 Python
对python过滤器和lambda函数的用法详解
2019/01/21 Python
python写日志文件操作类与应用示例
2019/07/01 Python
Django自带的加密算法及加密模块详解
2019/12/03 Python
Interhome丹麦:在线预订度假屋和公寓
2019/07/18 全球购物
Trench London官方网站:高级风衣和意大利皮夹克
2020/07/11 全球购物
岗位职责定义及内容
2013/11/08 职场文书
机械设计职业生涯规划书
2013/12/27 职场文书
旅游管理毕业生自荐信范文
2014/03/19 职场文书
信用社竞聘演讲稿
2014/05/16 职场文书
学雷锋倡议书
2015/01/19 职场文书
工地食品安全责任书
2015/05/09 职场文书
Laravel中获取IP的真实地理位置
2021/04/01 PHP
如何使用Python提取Chrome浏览器保存的密码
2021/06/09 Python
我的收音机情缘
2022/04/05 无线电