前言
跨域问题在Web开发中如影随形,而Django框架为我们提供了解决方案。本文将解析跨域原理,并介绍Django中处理跨域请求与CSRF防护的策略,助您轻松应对挑战。
跨域报错:Access to XMLHttpRequest at ‘http://127.0.0.1:8000/’ from origin ‘http://localhost:8080’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.
一、为什么会出现跨域?
出于浏览器的同源策略限制。
同源策略(Sameoriginpolicy)
是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。同源策略
会阻止一个域的javascript
脚本和另外一个域的内容进行交互。所谓同源
(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)
二、什么是跨域
当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域
当前页面url | 被请求页面url | 是否跨域 | 原因 |
http://www.baidu.com | http://www.baidu.com/index.html | 否 | 同源(协议、域名、端口号相同) |
http://www.baidu.com | https://www.baidu.com/index.html | 跨域 | 协议不同(http / https) |
http://www.baidu.com | http://www.google.com | 跨域 | 主域名不同(baidu / google) |
http://www.baidu.com | http://blog.baidu.com | 跨域 | 子域名不同(www / blog) |
http://www.baidu.com: 8080/ | http://www.baidu.com:8888/ | 跨域 | 端口号不同(8080 / 8888) |
三、跨域请求解决办法(Django)
3.1 安装第三方扩展:
pip install django-cors-headers
3.2 修改配置信息–setting.py:
注册corsheaders
:
# settings.py INSTALLED_APPS = ( ... 'corsheaders', ... )
添加中间件 — settings.py:
注意放在第一条,第一时间进行处理:
# settings.py MIDDLEWARE = [ # 添加跨域中间件 'corsheaders.middleware.CorsMiddleware', 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', # 'django.middleware.csrf.CsrfViewMiddleware', # 关闭csrf验证 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ]
配置参数 settings.py,允许所有源访问:
# settings.py CORS_ORIGIN_ALLOW_ALL = True
3.3 配置访问规则或白名单:
# settings.py 允许所有域名跨域(优先选择) CORS_ORIGIN_ALLOW_ALL = True # 配置白名单 # CORS_ORIGIN_WHITELIST = ( # '*' # # '127.0.0.1:8000', # # 'localhost:8000', # # '127.0.0.1:8080', # # 'localhost:8080', #'ads-cms-api.aataotao.com:8000' #'taoduoduo-test.oss-cn-#shenzhen.aliyuncs.com:80', # 线上 # #'10.0.2.187:8080' # 本地 #)
3.4 跨域Cookie配置
允许django响应Cookie:
# settings.py CORS_ALLOW_CREDENTIALS = True
在前端发起ajax请求的时候,请求中需要配置:
xhrFields:{withCredentials:true}, 与后端跨域配合设置,配置允许前端携带cookie
3.5 前端代码示例:
首先在html中引入jquery源码,配置ajax:
<script src="js/jquery-2.2.0.min.js"></script>
$.ajax({ url:"http://127.0.0.1:8000/app/collects/", dataType:'json',//设置返回数据类型 type:"GET",//请求方式 //data: xhrFields:{withCredentials:true},//设置支持携带cookie success:function(response){ console.log('请求成功'); }, error:function(){ console.log('请求失败'); }, async:true//是否异步 })
另: Django Web中 CSRF
在前端即templates中的html页面中添加
{% csrf_token %}
例如:login.html
<form action="http://127.0.0.1:8000/login/" method="post"> {% csrf_token %} <input type="text" name="user" placeholder="username" class="input-item"> <input type="text" name="phone" placeholder="phone" class="input-item"> <input type="password" name="password" placeholder="password" class="input-item"> <input type="submit" class="btn" value="login"> </form>