限制了浏览器往不同的源发请求,阻止读取响应数据。
<div >
<button id="btn">点我获取数据</button>
</div>
$('#btn').click(function () {
$.ajax({
url:'http://127.0.0.1:8001/index/',
success:function (res) {
console.log(res)
},
error:function (err) {
console.log(err)
}
})
})
所报错误:
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 标签的请求地址最后的 /
<!-- a标签 实现跨域-->
<a href="http://127.0.0.1:8001/index">点击获取 数据</a>
<!-- form表单提交post 实现跨域-->
<form action="http://127.0.0.1:8001/index/" method="post">
<input type="text" name="">
<button>提交</button>
</form>
def index(request):
if request.method == 'POST':
print(request.POST.get('name'))
return HttpResponse('form 200 OK')
return HttpResponse('{}'.format('a标签请求'))
写法:
<script>
// 定义一个 函数 用于接收返回的数据
function func(data){
console.log(data)
}
</script>
<!-- 引用服务器的接口实现数据传递 -->
<script src="http://127.0.0.1:8001/index"></script>
<!-- 相当于执行 func函数 -->
<script>
func(data)
</script>
"func(data)"
函数 的 调用 字符串形式 前端会自动根据函数名调用 定义好的 函数对象并且接收数据def index(request):
import json
data = {'name': '张紫益', 'age': 18}
# 返回一个函数的 调用方法
return HttpResponse('index({})'.format(json.dumps(data, ensure_ascii=False)))
缺点:
? 前后端都要支持
? 只能发GET请求
同时满足以下两个条件的是简单请求:
(1) 请求方法是一下三种方法之一:
(2) HTTP 的头信息不超过一下几种字段
前端正常 提交 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 MiddlewareMixin
class 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请求 :设置响应头 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
前端:
data = ' {'name': '张紫益', 'age': 18}'
// 序列化 parse 解析
var obj = JSON.parse(data)
console.log(obj)
// 反序列化
var str =JSON.stringify(obj)
console.log(str)
使用django f夫人
详见博客 同源策略及JSONP、CORS跨域
安装
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 = False
CORS_ORIGIN_WHITELIST = (
# '<YOUR_DOMAIN>[:PORT]',
'127.0.0.1:8080'
)
原文:https://www.cnblogs.com/zhang-zi-yi/p/10800587.html