补充知识:【与跨域无关】
1、简单请求与复杂请求区别?
复杂请求会先发出一个预请求,我们也叫预检,OPTIONS请求,简单请求则没有
2、如何区分简单请求与复杂请求?
简单请求:
HTTP方法是下列方法之一
HEAD,GET,POST
HTTP头信息不超出以下几种字段
Accept,Accept-Language,Last-Event-ID,Content-Type(application/x-www-form-urlencoded,multipart/form-data,text/plain 三种其中之一)
复杂请求:
不满足上述任何一个条件的请求,是复杂请求
--------------------------------分割线-------------------------------------
跨域
1、跨域概念:
浏览器访问地址和ajax请求的地址,两者域名或者端口不同,叫做跨域
2、产生原因:
浏览器的同源策略~
浏览器访问地址和ajax请求的地址域名或端口不一样,ajax就被阻止,为了安全
3、例外情况:
浏览器只阻止表单以及ajax请求,并不会阻止src请求,所以我们的cnd,图片等src请求都可以发
4、解决办法:
第一种:jsonp:实现原理是根据浏览器不阻止src请求入手
class Test(APIView): def get(self, request): callback = request.query_params.get("callback", "") ret = callback + "(" + "'success'" + ")" return HttpResponse(ret)
<button id="btn_one">点击我向JsonP1发送请求</button> <script> // 测试发送请求失败 跨域不能得到数据 $('#btn_one').click(function () { $.ajax({ url: "http://127.0.0.1:8000/jsonp1", type: "get", success: function (response) { console.log(response) } }) }); function handlerResponse(response) { alert(response) }; window.onload = function () { $("#btn_one").click(function () { let script_ele = document.createElement("script"); script_ele.src = "http://127.0.0.1:8000/jsonp1?callback=handlerResponse"; document.body.insertBefore(script_ele, document.body.firstChild); }) } </script>
JsonP解决跨域只能发送get请求,并且实现起来需要前后端交互比较多。
第二种:在中间件添加响应头
first、先在项目目录下新建midwares/my_midware.py
second、
from django.utils.deprecation import MiddlewareMixin class MyCors(MiddlewareMixin): def process_response(self, request, response): response["Access-Control-Allow-Origin"] = "*" if request.method == "OPTIONS": response["Access-Control-Allow-Headers"] = "Content-Type" response["Access-Control-Allow-Methods"] = "DELETE, PUT, POST" return response
third、注册
response["Access-Control-Allow-Origin"]="*" 告诉浏览器任何跨域都不拦截
复杂请求会有OPTIONS预检,还需要额外加Allow-Methods=“DELETE, PUT, POST”表示这三种请求不跨域
如果POST请求发的是JSON格式,JSON是复杂请求,content-type不是简单请求的三种,要加上Allow-Headers=“Content-Type”表示content-type不跨域