Python的Django应用程序解决AJAX跨域访问问题的方法

所属分类: 脚本专栏 / python 阅读数: 910
收藏 0 赞 0 分享

引子
使用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="https://cdn.zhanzhang360.cn/imgupload/006165/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页说明。

更多精彩内容其他人还在看

深入浅析python3中的unicode和bytes问题

在python3中,有两种字符串类型,默认的就是str,即unicode,也叫做文本类型。这篇文章主要介绍了python3中的unicode和bytes问题,需要的朋友可以参考下
收藏 0 赞 0 分享

python3 自动识别usb连接状态,即对usb重连的判断方法

今天小编就为大家分享一篇python3 自动识别usb连接状态,即对usb重连的判断方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
收藏 0 赞 0 分享

python二进制文件的转译详解

这篇文章主要介绍了python二进制文件的转译详解的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
收藏 0 赞 0 分享

python字符串中匹配数字的正则表达式

正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。这篇文章主要介绍了python字符串中匹配数字的正则表达式 ,需要的朋友可以参考下
收藏 0 赞 0 分享

在Python中COM口的调用方法

今天小编就为大家分享一篇在Python中COM口的调用方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
收藏 0 赞 0 分享

Python read函数按字节(字符)读取文件的实现

这篇文章主要介绍了Python read函数按字节(字符)读取文件的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

python读取图片的方式,以及将图片以三维数组的形式输出方法

今天小编就为大家分享一篇python读取图片的方式,以及将图片以三维数组的形式输出方法,具有好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
收藏 0 赞 0 分享

在python中利用numpy求解多项式以及多项式拟合的方法

今天小编就为大家分享一篇在python中利用numpy求解多项式以及多项式拟合的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
收藏 0 赞 0 分享

Python正则表达式匹配数字和小数的方法

这篇文章主要介绍了Python正则匹配数字和小数的方法,本文通过示例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

python读写配置文件操作示例

这篇文章主要介绍了python读写配置文件操作,结合实例形式分析了Python针对ini配置文件的读取、解析、写入等相关操作技巧,需要的朋友可以参考下
收藏 0 赞 0 分享
查看更多