中间件的使用一(设置跨域访问)
一、关于跨域的认识
由于浏览器存在同源策略机制,同源策略会阻止从一个源加载的文档、脚本获取、设置一个源加载的文档的属性。
何为所谓同源:
- 1、相同的协议(
http
、https
) - 2、相同的域名、或者主机
ip
- 3、相同的端口号
特点:由于同源策略是浏览器的限制,所以请求的发送和响应是可以进行,只不过浏览器不接受罢了。
浏览器同源策略并不是对所有的请求均制约:
- 制约:
XmlHttpRequest
- 不制约:
img
、iframe
、script
等具有src
属性的标签
二、关于常见解决跨域的方式
1、前端出现跨域的问题报错如下
Failed to load http://localhost:9000/test1/: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:63343' is therefore not allowed access.
2、
jsonp
原理利用
script
标签的sr
c属性(浏览器允许script
标签跨域),利用js
脚本动态的在头部引入跨域的地址,主要不足:只能是get
请求,不能是post
等别的请求// 方法一、动态的添加跨域地址 function Jsonp1(){ var tag = document.createElement('script'); tag.src = "http://c2.com:8000/test/"; document.head.appendChild(tag); document.head.removeChild(tag); } function Jsonp2(){ $.ajax({ url: "http://c2.com:8000/test/", type: 'GET', dataType: 'JSONP', success: function(data, statusText, xmlHttpRequest){ console.log(data); } }) }
3、
CORS
设置浏览器允许跨域请求,其本质是设置请求响应头,使浏览器允许跨域请求(主要工作是后端设置)。- 4、更多的跨域请求请参考
三、关于简单请求与非简单请求
1、满足简单请求的条件(需要同时满足)
- 1.请求方式:
HEAD
、GET
、POST
- 2.请求头信息:
Content-Type
对应其中任意一个(application/x-www-form-urlencoded
,multipart/form-data
,text/plain
)
- 1.请求方式:
2、简单请求与非简单请求的区别
- 1.简单请求只请求一次
- 2.非简单请求,在发送数据之前会先进行一次预检,只有预检通过后才能再发送一次请求用于数据传输.
3、关于预检的认识
- 1.请求方式:
OPTIONS
- 2.预检其实做检查,检查如果通过则允许传输数据,检查不通过则不再发送真正想要发送的消息
- 3.如果复杂请求是
PUT
等请求,则服务端需要设置允许某请求(Access-Control-Request-Method
),否则"预检"不通过 - 4.如果复杂请求设置了请求头,则服务端需要设置允许某请求头(
Access-Control-Request-Headers
),否则"预检"不通过
- 1.请求方式:
四、使用中间件实现跨域访问
1、导包
from django.utils.deprecation import MiddlewareMixin
2、定义中间件
class CORSMiddleWare(MiddlewareMixin): """ 设置跨域的中间件 """ def process_response(self, request, response): # 添加请求头 # 允许你的域名来获取数据(也可以指定域名) response['Access-Control-Allow-Origin'] = '*' if request.method == 'OPTIONS': # 允许你携带Content-Type请求头,也可以设置别的自定义字段(不设置客户端设置的就不能通过预检) response['Access-Control-Allow-Headers'] = 'Content-Type,k1, k2' # 允许你发送DELETE,PUT的请求方式 response['Access-Control-Allow-Methods'] = 'DELETE,PUT' # 允许设置缓存时间 response['Access-Control-Max-Age'] = 20 return response
3、注册
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', 'middle.cors_middle_ware.CORSMiddleWare', # 自定义跨域中间件 ]
4、客户端测试
$('#btn').on('click', function () { $.ajax({ url: 'http://localhost:9000/test1/', method: 'post', data: { username: $('#name').val() }, headers: { 'k1': 'hello' }, success: function (data) { console.log(data) } }) })
五、补充说明,使用django-cors-headers
插件来实现跨域访问
- 1、文档地址