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实现把数字转换成中文
Jun 29 Python
Python中内置数据类型list,tuple,dict,set的区别和用法
Dec 14 Python
Python3 Random模块代码详解
Dec 04 Python
python使用生成器实现可迭代对象
Mar 20 Python
儿童学习python的一些小技巧
May 27 Python
Python爬虫包BeautifulSoup实例(三)
Jun 17 Python
python Matplotlib底图中鼠标滑过显示隐藏内容的实例代码
Jul 31 Python
django基于存储在前端的token用户认证解析
Aug 06 Python
wxPython实现带颜色的进度条
Nov 19 Python
Python阶乘求和的代码详解
Feb 14 Python
Python 实现黑客帝国中的字符雨的示例代码
Feb 20 Python
python GUI库图形界面开发之PyQt5窗口类QMainWindow详细使用方法
Feb 26 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
多人战的战术与战略
2020/03/04 星际争霸
php连接函数implode与分割explode的深入解析
2013/06/26 PHP
php加速器eAccelerator的配置参数、API详解
2014/05/05 PHP
PHP开发框架kohana中处理ajax请求的例子
2014/07/14 PHP
使用jquery hover事件实现表格的隔行换色功能示例
2013/09/03 Javascript
Javascript全局变量var与不var的区别深入解析
2013/12/09 Javascript
jQuery实现的支持IE的html滑动条
2015/03/16 Javascript
jquery插件jSignature实现手动签名
2015/05/04 Javascript
详解Vue快速零配置的打包工具——parcel
2018/01/16 Javascript
解决vue页面刷新或者后退参数丢失的问题
2018/03/13 Javascript
SVG实现时钟效果
2018/07/17 Javascript
Node.js实现简单的爬取的示例代码
2019/06/25 Javascript
JS加载解析Markdown文档过程详解
2020/05/19 Javascript
Nuxt 嵌套路由nuxt-child组件用法(父子页面组件的传值)
2020/11/05 Javascript
[02:08]2014DOTA2国际邀请赛 430专访:力争取得小组前二
2014/07/11 DOTA
python3.5实现socket通讯示例(TCP)
2017/02/07 Python
python爬虫入门教程--HTML文本的解析库BeautifulSoup(四)
2017/05/25 Python
Python 将Matrix、Dict保存到文件的方法
2018/10/30 Python
Pandas中Series和DataFrame的索引实现
2019/06/27 Python
wxpython布局的实现方法
2019/11/01 Python
pytorch查看torch.Tensor和model是否在CUDA上的实例
2020/01/03 Python
Python计算IV值的示例讲解
2020/02/28 Python
Python 读取WAV音频文件 画频谱的实例
2020/03/14 Python
Python计算指定日期是今年的第几天(三种方法)
2020/03/26 Python
keras 两种训练模型方式详解fit和fit_generator(节省内存)
2020/07/03 Python
python两种注释用法的示例
2020/10/09 Python
澳大利亚领先的折扣药房:Chemist Direct(有中文站)
2018/11/24 全球购物
双立人美国官方商店:ZWILLING集团餐具和炊具
2020/05/07 全球购物
单位办理社保介绍信
2014/01/10 职场文书
高校十八大报告感想
2014/01/27 职场文书
护士毕业生自我鉴定
2014/02/08 职场文书
信息科学与技术专业求职信范文
2014/02/20 职场文书
承诺书样本
2014/08/30 职场文书
2015年读书月活动总结
2015/03/26 职场文书
离婚纠纷代理词
2015/05/23 职场文书
深入解读Java三大集合之map list set的用法
2021/11/11 Java/Android