一、同源策略
同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现 请求的url地址,必须与浏览器上的url地址处于同域上,也就是域名,端口,协议相同. 比如:我在本地上的域名是127.0.0.1:8000,请求另外一个域名:127.0.0.1:8001一段数据 浏览器上就会报错,个就是同源策略的保护,如果浏览器对javascript没有同源策略的保护,那么一些重要的机密网站将会很危险
如果跨域发送请求,会出错
已拦截跨源请求:同源策略禁止读取位于 http://127.0.0.1:8001/index/ 的远程资源。(原因:CORS 头缺少 'Access-Control-Allow-Origin')。
1)举例,前端模板代码编写(get简单请求)
http://127.0.0.1:8000/test
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <script src="/static/jquery-3.3.1.js"></script> <title>Title</title> </head> <body> <button id="btn">点我向http://127.0.0.1:8001/发请求</button> </body> <script> $("#btn").click(function () { $.ajax({ url:'http://127.0.0.1:8001/index/', type:'get', success:function (data) { alert(data) } }) }) </script> </html>
直接向http://127.0.0.1:8001/index发送请求,获取http://127.0.0.1:8001/index数据
def index(request): return HttpResponse('ok')
2) 解决该问题,需要在被请求的服务器允许其他服务器的请求
def index(request): obj=HttpResponse('ok') # obj['Access-Control-Allow-Origin'] = '*' # 允许任意请求 obj['Access-Control-Allow-Origin'] = 'http://127.0.0.1://8000' return obj
二、跨域问题的简单请求和非简单请求
* 简单请求和非简单请求的区别? 简单请求:一次请求 非简单请求:两次请求,在发送数据之前会先发一次请求用于做“预检”,只有“预检”通过后才再发送一次请求用于数据传输。 * 关于“预检” - 请求方式:OPTIONS - “预检”其实做检查,检查如果通过则允许传输数据,检查不通过则不再发送真正想要发送的消息 - 如何“预检” => 如果复杂请求是PUT等请求,则服务端需要设置允许某请求,否则“预检”不通过 Access-Control-Request-Method => 如果复杂请求设置了请求头,则服务端需要设置允许某请求头,否则“预检”不通过 Access-Control-Request-Headers
1) 示例 将前端改为put请求
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <script src="/static/jquery-3.3.1.js"></script> <title>Title</title> </head> <body> <button id="btn">点我向http://127.0.0.1:8001/发请求</button> </body> <script> $("#btn").click(function () { $.ajax({ url:'http://127.0.0.1:8001/index/', type:'put', success:function (data) { alert(data) } }) }) </script> </html>
处理该问题: obj['Access-Control-Allow-Methods'] = 'put'
def index(request): obj=HttpResponse('ok') if request.method == 'OPTIONS': obj['Access-Control-Allow-Methods'] = 'PUT' obj['Access-Control-Allow-Origin'] = 'http://127.0.0.1:8000' return obj
测试的时候,需要注释掉csrf的中间件
2)支持的数据格式
Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain
3)发送数据时的跨域问题。contentType:'application/json'
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <script src="/static/jquery-3.3.1.js"></script> <title>Title</title> </head> <body> <button id="btn">点我向http://127.0.0.1:8001/发请求</button> </body> <script> $("#btn").click(function () { $.ajax({ url:'http://127.0.0.1:8001/index/', type:'put', contentType:'application/json', data:'{"name":"user"}', success:function (data) { alert(data) } }) }) </script> </html>
被请求的服务器视图函数编写
def index(request): obj=HttpResponse('ok') if request.method == 'OPTIONS': obj['Access-Control-Allow-Methods'] = 'PUT' obj['Access-Control-Allow-Headers'] = '*' obj['Access-Control-Allow-Origin'] = 'http://127.0.0.1:8000' return obj
三、跨域请求全局处理
1)创建一个中间件
from django.utils.deprecation import MiddlewareMixin class Mymiddleware(MiddlewareMixin): def process_response(self,request,response): if request.method == 'OPTIONS': response['Access-Control-Allow-Methods'] = 'PUT' response['Access-Control-Allow-Headers'] = '*' response['Access-Control-Allow-Origin'] = '*' return response
2)settings中导入该中间件
MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', # 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'app01.mymiddel.Mymiddleware' # 导入内容 ]
3)视图函数就变的和以前一样了。
def index(request): obj=HttpResponse('ok') return obj