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发送邮件实例讲解(python发邮件附件可以使用email模块实现)
Dec 03 Python
使用Python开发windows GUI程序入门实例
Oct 23 Python
Python输出PowerPoint(ppt)文件中全部文字信息的方法
Apr 28 Python
Python实现的RSS阅读器实例
Jul 25 Python
对pandas的dataframe绘图并保存的实现方法
Aug 05 Python
使用Python实现博客上进行自动翻页
Aug 23 Python
python实现大转盘抽奖效果
Jan 22 Python
Python二叉搜索树与双向链表转换算法示例
Mar 02 Python
利用Python实现Shp格式向GeoJSON的转换方法
Jul 09 Python
python3获取文件中url内容并下载代码实例
Dec 27 Python
Django权限设置及验证方式
May 13 Python
python 字符串格式化的示例
Sep 21 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使用mb_check_encoding检查字符串在指定的编码里是否有效
2013/11/07 PHP
AES加解密在php接口请求过程中的应用示例
2016/10/26 PHP
yii2实现 &quot;上一篇,下一篇&quot; 功能的代码实例
2017/02/04 PHP
一些易混淆且不常用的属性,希望有用
2007/01/29 Javascript
javascript 页面只自动刷新一次
2009/07/10 Javascript
js弹出确认是否删除对话框
2014/03/27 Javascript
微信小程序前端源码逻辑和工作流
2016/09/25 Javascript
微信小程序加载更多 点击查看更多
2016/11/29 Javascript
详解Javascript数据类型的转换规则
2016/12/12 Javascript
AngularJS实现tab选项卡的方法详解
2017/07/05 Javascript
分析javascript原型及原型链
2018/03/18 Javascript
eslint 的三大通用规则详解
2019/05/16 Javascript
微信小程序如何连接Java后台
2019/08/08 Javascript
Vue 的双向绑定原理与用法揭秘
2020/05/06 Javascript
用Angular实现一个扫雷的游戏示例
2020/05/15 Javascript
[56:35]DOTA2上海特级锦标赛C组小组赛#1 OG VS Archon第二局
2016/02/27 DOTA
详解python上传文件和字符到PHP服务器
2017/11/24 Python
对pandas中to_dict的用法详解
2018/06/05 Python
python实现猜数字小游戏
2020/03/24 Python
Python操作json的方法实例分析
2018/12/06 Python
Python全局锁中如何合理运用多线程(多进程)
2019/11/06 Python
布隆过滤器的概述及Python实现方法
2019/12/08 Python
Keras使用tensorboard显示训练过程的实例
2020/02/15 Python
常用UNIX 命令(Linux的常用命令)
2015/12/26 面试题
软件测试英文面试题
2012/10/14 面试题
毕业生找工作推荐信
2013/11/21 职场文书
质检部职责
2013/12/28 职场文书
《只有一个地球》教学反思
2014/02/14 职场文书
周年庆典主持词
2014/04/02 职场文书
《春到梅花山》教学反思
2014/04/16 职场文书
春季防火方案
2014/05/10 职场文书
保安公司服务承诺书
2014/05/28 职场文书
企业领导班子四风对照检查材料
2014/09/27 职场文书
python实现监听键盘
2021/04/26 Python
浅谈Python中的函数(def)及参数传递操作
2021/05/25 Python
nginx作grpc的反向代理踩坑总结
2021/07/07 Servers