浏览器的同源策略
限制了浏览器往不同的源发请求,阻止读取响应数据。
所报错误:
Access to XMLHttpRequest at 'http://127.0.0.1:8001/index' from origin 'http://localhost:63342' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
a标签 以及form表单的 请求不会被浏览器阻止
注意 from 标签的请求地址最后的
/
点击获取 数据
def index(request): if request.method == 'POST': print(request.POST.get('name')) return HttpResponse('form 200 OK') return HttpResponse('{}'.format('a标签请求'))
跨域
JSONP 实现
写法:
- 使用引用 JS 文件的 方式 给服务器发送请求
- 在引用之前定义一个函数
- 在view 视图中 返回 一个
"func(data)"
函数 的 调用 字符串形式 前端会自动根据函数名调用 定义好的 函数对象并且接收数据
def index(request): import json data = {'name': '张紫益', 'age': 18} # 返回一个函数的 调用方法 return HttpResponse('index({})'.format(json.dumps(data, ensure_ascii=False)))
缺点:
前后端都要支持
只能发GET请求
CORS跨域
简单请求和非简单请求
同时满足以下两个条件的是简单请求:
(1) 请求方法是一下三种方法之一:
- HEAD
- GET
- POST
(2) HTTP 的头信息不超过一下几种字段
- Accept
- Accept-Language
- Content-Language
- Last-Event-ID
- Content--Type: 只限于 application/x-www-form-urlencoded, multipart/form-data,texxt/plain
简单请求
前端正常 提交 ajax 请求
后端要给响应头加上
Access-Control-Allow-Origin
data = {'name': '张紫益', 'age': 18} ret = HttpResponse('{}'.format(json.dumps(data, ensure_ascii=False))) # 给 response 对象 添加响应头 指定 发送请求的主机地址 ret['Access-Control-Allow-Origin'] = 'http://localhost:63342' # 或者 让所有的 简单请求 都通过 ret['Access-Control-Allow-Origin'] = '*' // * 所有 # 启用 控制 允许 起源 return ret
将响应求头加入到 中间件中 避免每次都要写
from django.utils.deprecation import MiddlewareMixinclass CORSMiddleware(MiddlewareMixin): def process_response(self, request, response): response['Access-Control-Allow-Origin'] = '*' return response# 注册中间件# 在中间件的 第一行注册 因为响应 是倒叙的
非简单请求:
区别 : 前段请求的 ajax 中 加入了 contenttype: 'application/json' 的 请求头
请求的 类型 就变成了
POTIONS
类型后端要给响应头加上
如果修改了Content-Type:
Access-Control-Allow-Headers
前端中
$('#btn').click(function () { $.ajax({ url:'http://127.0.0.1:8001/index/', type:'post',// 设置的 非简单 请求 会 将请求方式 该为 POTIONS contentType:'application/json', success:function (res) { var aa = JSON.parse(res) console.log(aa) console.log(JSON.stringify(aa)) }, error:function (err) { console.log(err) } })})
Django 中
data = {'name': '张紫益', 'age': 18} ret = HttpResponse('{}'.format(json.dumps(data, ensure_ascii=False))) # 判断 请求 是否是 非简单请求 if request.method =='OPTIONS': # 设置 响应头让其 通过 ret['Access-Control-Allow-Headers'] = 'content-type' return ret
PUT或DELETE请求
如果使用的是PUT或DELETE请求 :设置响应头
Access-Control-Allow-Methods
= 'PUT'data = {'name': '张紫益', 'age': 18} ret = HttpResponse('{}'.format(json.dumps(data, ensure_ascii=False))) # 判断 请求 是否是 非简单请求 if request.method =='OPTIONS': # 设置 响应头让其 通过 ret['Access-Control-Allow-Headers'] = 'content-type' # 设置 put delete 请求的 响应头 ret['Access-Control-Allow-Methods'] = 'PUT, DELETE' return ret
前端:
JSON 的 序列化 与反序列化
data = ' {'name': '张紫益', 'age': 18}'// 序列化 parse 解析var obj = JSON.parse(data)console.log(obj)// 反序列化var str =JSON.stringify(obj)console.log(str)
django-core-headers
使用django f夫人
详见博客
安装
pip install django-cors-headers
注册APP
INSTALLED_APPS = [ ... 'app01.apps.App01Config', 'corsheaders', # 将 corsheaders 这个APP注册]
添加中间件
必须放在最前面,因为要先解决跨域的问题。只有允许跨域请求,后续的中间件才会正常执行。
MIDDLEWARE = [ 'corsheaders.middleware.CorsMiddleware', # 添加中间件 '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',]
配置
你可以选择不限制跨域访问 允许所有
CORS_ORIGIN_ALLOW_ALL = True
或者你可以选择设置允许访问的白名单
CORS_ORIGIN_ALLOW_ALL = FalseCORS_ORIGIN_WHITELIST = ( # '[:PORT]', '127.0.0.1:8080')