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实现strcmp函数功能示例
Mar 25 Python
简介Django框架中可使用的各类缓存
Jul 23 Python
Python 文件管理实例详解
Nov 10 Python
python购物车程序简单代码
Apr 18 Python
Linux下python制作名片示例
Jul 20 Python
解决tensorflow模型参数保存和加载的问题
Jul 26 Python
使用python将时间转换为指定的格式方法
Nov 12 Python
python树莓派红外反射传感器
Jan 21 Python
python脚本开机自启的实现方法
Jun 28 Python
在服务器上安装python3.8.2环境的教程详解
Apr 26 Python
python中如何使用虚拟环境
Oct 14 Python
python如何为list实现find方法
May 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防注
2007/01/15 PHP
php若干单维数组遍历方法的比较
2011/09/20 PHP
php中Array2xml类实现数组转化成XML实例
2014/12/08 PHP
smarty自定义函数用法示例
2016/05/20 PHP
PHP入门教程之使用Mysqli操作数据库的方法(连接,查询,事务回滚等)
2016/09/11 PHP
ThinkPHP的SAE开发相关注意事项详解
2016/10/09 PHP
Laravel关联模型中过滤结果为空的结果集(has和with区别)
2018/10/18 PHP
用jquery实现自定义风格的滑动条实现代码
2011/04/26 Javascript
jquery+json实现数据列表分页示例代码
2013/11/15 Javascript
jQuery实现级联菜单效果(仿淘宝首页菜单动画)
2014/04/10 Javascript
关于在Servelet中如何获取当前时间的操作方法
2016/06/28 Javascript
Bootstrap按钮功能之查询按钮和重置按钮
2016/10/26 Javascript
javascript构造函数以及原型对象的理解
2017/01/13 Javascript
HTML中使背景图片自适应浏览器大小实例详解
2017/04/06 Javascript
详解vue-cli项目中用json-sever搭建mock服务器
2017/11/02 Javascript
HTML5+JS+JQuery+ECharts实现异步加载问题
2017/12/16 jQuery
Vue仿今日头条实例详解
2018/02/06 Javascript
VUE v-model表单数据双向绑定完整示例
2019/01/21 Javascript
JavaScript this使用方法图解
2020/02/04 Javascript
vue 授权获取微信openId操作
2020/11/13 Javascript
[01:07:11]Secret vs Newbee 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/17 DOTA
Python操作Access数据库基本步骤分析
2016/09/19 Python
Python切片操作实例分析
2018/03/16 Python
解决每次打开pycharm直接进入项目的问题
2018/10/28 Python
在win10和linux上分别安装Python虚拟环境的方法步骤
2019/05/09 Python
Django后端发送小程序微信模板消息示例(服务通知)
2019/12/17 Python
Python单链表原理与实现方法详解
2020/02/22 Python
HTML5 canvas 瀑布流文字效果的示例代码
2018/01/31 HTML / CSS
JAVA和C++的区别
2013/10/06 面试题
保研推荐信
2014/05/09 职场文书
应届生求职信
2014/05/31 职场文书
药店促销活动策划方案
2014/08/24 职场文书
小学教师个人总结
2015/02/05 职场文书
狂人日记读书笔记
2015/06/30 职场文书
六年级作文之自救
2019/12/19 职场文书
使用JS实现简易计算器
2021/06/14 Javascript