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中self原理实例分析
Apr 30 Python
Python实现简易端口扫描器代码实例
Mar 15 Python
使用Python搭建虚拟环境的配置方法
Feb 28 Python
Python matplotlib通过plt.scatter画空心圆标记出特定的点方法
Dec 13 Python
cProfile Python性能分析工具使用详解
Jul 22 Python
Python对象的属性访问过程详解
Mar 05 Python
python GUI库图形界面开发之PyQt5布局控件QHBoxLayout详细使用方法与实例
Mar 06 Python
在 Pycharm 安装使用black的方法详解
Apr 02 Python
Python基于DB-API操作MySQL数据库过程解析
Apr 23 Python
Python通过两个dataframe用for循环求笛卡尔积
Apr 29 Python
Python collections.defaultdict模块用法详解
Jun 18 Python
python os模块在系统管理中的应用
Jun 22 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
win7下memCache的安装过程(具体操作步骤)
2013/06/28 PHP
PHP如何根据文件头检测文件类型实例代码
2018/10/14 PHP
PHP设计模式之装饰器(装饰者)模式(Decorator)入门与应用详解
2019/12/13 PHP
javascript获取当前日期时间及其它操作函数
2011/01/11 Javascript
jQuery数组处理方法汇总
2011/06/20 Javascript
JavaScript 函数参数是传值(byVal)还是传址(byRef) 分享
2013/07/02 Javascript
js实现按钮控制图片360度翻转特效的方法
2015/02/17 Javascript
JS根据生日算年龄的方法
2015/05/05 Javascript
jQuery幻灯片特效代码分享--鼠标滑过按钮时切换(2)
2020/11/18 Javascript
详解ES6中的let命令
2020/04/05 Javascript
js原生之焦点图转换加定时器实例
2016/12/12 Javascript
AngularJS的依赖注入实例分析(使用module和injector)
2017/01/19 Javascript
jQuery validate 验证radio实例
2017/03/01 Javascript
jQuery弹出窗口简单实现代码
2017/03/09 Javascript
微信小程序组件之srcoll-view的详解
2017/10/19 Javascript
《javascript少儿编程》location术语总结
2018/05/27 Javascript
JS中的防抖与节流及作用详解
2019/04/01 Javascript
NodeJS读取分析Nginx错误日志的方法
2019/05/14 NodeJs
Vue的属性、方法、生命周期实例代码详解
2019/09/17 Javascript
Node.js API详解之 zlib模块用法分析
2020/05/19 Javascript
Element图表初始大小及窗口自适应实现
2020/07/10 Javascript
Postman环境变量全局变量使用方法详解
2020/08/13 Javascript
详解Python中的array数组模块相关使用
2016/07/05 Python
Python遍历numpy数组的实例
2018/04/04 Python
Python socket连接中的粘包、精确传输问题实例分析
2020/03/24 Python
python3 sleep 延时秒 毫秒实例
2020/05/04 Python
Python基于Tkinter编写crc校验工具
2020/05/06 Python
Python爬虫定时计划任务的几种常见方法(推荐)
2021/01/15 Python
CSS3盒子模型详解
2013/04/24 HTML / CSS
农村婚礼主持词
2014/03/13 职场文书
教师演讲稿大全
2014/05/16 职场文书
标准毕业生自荐信
2014/06/24 职场文书
经营场所证明范本
2015/06/19 职场文书
Oracle更换为MySQL遇到的问题及解决
2021/05/21 Oracle
从np.random.normal()到正态分布的拟合操作
2021/06/02 Python
Win10系统下配置Java环境变量
2021/06/13 Java/Android