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中for循环详解
Jan 17 Python
Python计算三维矢量幅度的方法
Jun 15 Python
详谈Python3 操作系统与路径 模块(os / os.path / pathlib)
Apr 26 Python
python删除字符串中指定字符的方法
Aug 13 Python
Python绘制KS曲线的实现方法
Aug 13 Python
Python运维开发之psutil库的使用详解
Oct 18 Python
对python文件读写的缓冲行为详解
Feb 13 Python
在Python中合并字典模块ChainMap的隐藏坑【推荐】
Jun 27 Python
Pycharm 使用 Pipenv 新建的虚拟环境(图文详解)
Apr 16 Python
Win10下用Anaconda安装TensorFlow(图文教程)
Jun 18 Python
python 中关于pycharm选择运行环境的问题
Oct 31 Python
pandas进行数据输入和输出的方法详解
Mar 23 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.ini中文版(1)
2006/10/09 PHP
PHP一些常用的正则表达式字符的一些转换
2008/07/29 PHP
fleaphp crud操作之find函数的使用方法
2011/04/23 PHP
PHP中根据IP地址判断城市实现城市切换或跳转代码
2012/09/04 PHP
php使用iconv中文截断问题的解决方法
2015/02/11 PHP
Zend Framework教程之Resource Autoloading用法实例
2016/03/08 PHP
php微信开发之百度天气预报
2016/11/18 PHP
PHP正则验证字符串是否为数字的两种方法并附常用正则
2019/02/27 PHP
Jquery 弹出层插件实现代码
2009/10/24 Javascript
JavaScript 页面编码与浏览器类型判断代码
2010/06/03 Javascript
js网页实时倒计时精确到秒级
2014/02/10 Javascript
JSONP跨域的原理解析及其实现介绍
2014/03/22 Javascript
javascript实现自动填写表单实例简析
2015/12/02 Javascript
基于Jquery插件实现跨域异步上传文件功能
2016/04/26 Javascript
javascript淘宝主图放大镜功能
2016/10/20 Javascript
Vue数据驱动模拟实现2
2017/01/11 Javascript
jQuery读取XML文件的方法示例
2017/02/03 Javascript
JavaScript实现的滚动公告特效【基于jQuery】
2019/07/10 jQuery
js 压缩图片的示例(只缩小体积,不更改图片尺寸)
2020/10/21 Javascript
深入剖析Python的爬虫框架Scrapy的结构与运作流程
2016/01/20 Python
python引入导入自定义模块和外部文件的实例
2017/07/24 Python
win10系统下Anaconda3安装配置方法图文教程
2018/09/19 Python
python 梯度法求解函数极值的实例
2019/07/10 Python
python爬取盘搜的有效链接实现代码
2019/07/20 Python
python web框架 django wsgi原理解析
2019/08/20 Python
余弦相似性计算及python代码实现过程解析
2019/09/18 Python
Python小程序之在图片上加入数字的代码
2019/11/26 Python
Python3中小括号()、中括号[]、花括号{}的区别详解
2020/11/15 Python
"引用"与多态的关系
2013/02/01 面试题
毕业生求职找工作的自我评价范文
2013/11/27 职场文书
2014年库房工作总结
2014/11/26 职场文书
2015年度保密工作总结
2015/04/24 职场文书
Python实现智慧校园自动评教全新版
2021/06/18 Python
yyds什么意思?90后已经听不懂00后讲话了……
2022/02/03 杂记
Python中time标准库的使用教程
2022/04/13 Python
MySQL中JOIN连接的基本用法实例
2022/06/05 MySQL