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 相关文章推荐
教你如何在Django 1.6中正确使用 Signal
Jun 22 Python
Python的Django框架使用入门指引
Apr 15 Python
安装dbus-python的简要教程
May 05 Python
对Python中内置异常层次结构详解
Oct 18 Python
Python os.rename() 重命名目录和文件的示例
Oct 25 Python
python微信聊天机器人改进版(定时或触发抓取天气预报、励志语录等,向好友推送)
Apr 25 Python
opencv python Canny边缘提取实现过程解析
Feb 03 Python
pyMySQL SQL语句传参问题,单个参数或多个参数说明
Jun 06 Python
基于OpenCV的网络实时视频流传输的实现
Nov 15 Python
Pycharm安装第三方库失败解决方案
Nov 17 Python
python自动打开浏览器下载zip并提取内容写入excel
Jan 04 Python
使用python向MongoDB插入时间字段的操作
May 18 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 时区的一点总结
2008/03/26 PHP
php mssql 日期出现中文字符的解决方法
2009/03/10 PHP
初品cakephp 入门基础
2012/02/16 PHP
php下载远程大文件(获取远程文件大小)的实例
2017/06/17 PHP
PHP中递归的实现实例详解
2017/11/14 PHP
JQUERY 对象与DOM对象之两者相互间的转换
2009/04/27 Javascript
filters.revealTrans.Transition使用方法小结
2010/08/19 Javascript
js事件冒泡实例分享(已测试)
2013/04/23 Javascript
在子窗口中关闭父窗口的一句代码
2013/10/21 Javascript
seajs中模块的解析规则详解和模块使用总结
2014/03/12 Javascript
理解javascript中的回调函数(callback)
2014/09/02 Javascript
深入理解javascript严格模式(Strict Mode)
2014/11/28 Javascript
一道关于JavaScript变量作用域的面试题
2016/03/08 Javascript
JQuery在循环中绑定事件的问题详解
2016/06/02 Javascript
微信小程序 教程之WXSS
2016/10/18 Javascript
JavaScript字符串对象(string)基本用法示例
2017/01/18 Javascript
jquery使用EasyUI Tree异步加载JSON数据(生成树)
2017/02/11 Javascript
jQuery树控件zTree使用方法详解(一)
2017/02/28 Javascript
小程序实现搜索界面 小程序实现推荐搜索列表效果
2019/05/18 Javascript
Jquery如何使用animation动画效果改变背景色的代码
2020/07/20 jQuery
Vue $emit()不能触发父组件方法的原因及解决
2020/07/28 Javascript
[42:36]DOTA2上海特级锦标赛B组败者赛 VG VS Spirit第二局
2016/02/26 DOTA
Python设计模式之迭代器模式原理与用法实例分析
2019/01/10 Python
使用pygame写一个古诗词填空通关游戏
2019/12/03 Python
VScode连接远程服务器上的jupyter notebook的实现
2020/04/23 Python
python中time包实例详解
2021/02/02 Python
H5新属性audio音频和video视频的控制详解(推荐)
2016/12/09 HTML / CSS
英国日常交易网站:Wowcher
2018/09/04 全球购物
澳大利亚家居用品零售商:Harris Scarfe
2020/10/10 全球购物
秘书行业自我鉴定范文
2013/12/30 职场文书
直接有效的自我评价
2014/01/11 职场文书
摄影专业毕业生求职信
2014/08/05 职场文书
2016元旦主持人开场白
2015/12/03 职场文书
一年之计:2019年下半年的计划
2019/05/07 职场文书
图文详解matlab原始处理图像几何变换
2021/07/09 Python
MySQL数据库实验实现简单数据库应用系统设计
2022/06/21 MySQL