7.Django如何实现跨域

1.同源策略

同源策略是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源, 即协议不同,域名不同或者端口不同的都是非同源的

浏览器只阻止表单以及 ajax 请求,并不会阻止 src 请求,所以能访问cnd,图片等 src 请求

2.简单/复杂请求

简单请求定义

  1. 只能使用get/post/head请求方式
  2. HTTP 头信息不超出以下几种字段Accept, Accept-Language,Content-Language, Last-Event-ID
  3. Content-Type只能是text/plain,multipart/form-data,application/x-www-from-urlencoded
  4. 请求中的任意XMLHttpRequestUpload 对象均没有注册任何事件监听器 (未验证),MLHttpRequestUpload 对象可以使用 XMLHttpRequest.upload 属性访问

注意

任何一个不满足上述要求的请求,即会被认为是复杂请求

3.CORS

CORS(Cross Origin Resource Sharing跨域资源共享)是一种允许当前域(domain)的资源(比如html/js/web service)被其他域(domain)的脚本请求访问的机制,通常由于同域安全策略(the same-origin security policy)浏览器会禁止这种跨域请求

4.如何解决跨域

方法一:添加响应头Access-Control-Allow-Origin

1.启动http://127.0.0.1:1010/app1

urls.py

from django.urls import path


from app2 import views

urlpatterns = [
    path('app1', views.app1),
]

views.py

from django.http import HttpResponse


def app1(request):
    my_response = HttpResponse("app1")
    return my_response

2.启动http://127.0.0.1:2020/app2

urls.py

from django.urls import path


from app2 import views

urlpatterns = [
    path('app2', views.app2),
]

views.py

from django.shortcuts import render


def app2(request):
    return render(request, 'app2.html')

app2.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>app2</title>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>

</head>
<body>
<h3>app2</h3>
<button id="btn">发送JSONP请求</button>
<script>
    function func(arg) {
        $('h3').append($('<p>').text(arg))
    }

    $("#btn").click(function () {
        $.ajax({
            url: "http://127.0.0.1:1010/app1/",
            type: "get",
            success: function (arg) {
                $('h3').append($('<p>').text(arg))
            }
        })
    });
</script>
</body>
</html>

3.访问http://127.0.0.1:2020/app2

报错:

cess to XMLHttpRequest at 'http://127.0.0.1:6060/app1/' from origin 'http://localhost:63342' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

解决

修改http://127.0.0.1:1010/app1views.py

from django.http import HttpResponse


def app1(request):
    my_response = HttpResponse("app1")
    my_response["Access-Control-Allow-Origin"] = "http://127.0.0.1:2020"
    if request.method == "OPTIONS":
        my_response["Access-Control-Allow-Methods"] = "PUT, DELETE"
        my_response["Access-Control-Allow-Headers"] = "content-type, X-CUSTOMER-HEADER"
        # 设置max age,浏览器端会进行缓存,没有过期之前真对同一个请求只会发送一次预检请求
        my_response["Access-Control-Max-Age"] = 86400
    return my_response

方法二:使用扩展django-cors-headers

安装

pip install django-cors-headers

添加应用

INSTALLED_APPS = (
    ...
    'corsheaders',
    ...
)

中间层设置

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    ...
]

添加白名单

CORS_ORIGIN_WHITELIST = (
    'http://127.0.0.1:2020',
    'http://127.0.0.1:1010',
)
CORS_ALLOW_CREDENTIALS = True  # 允许携带cookie

5.跨域实现流程

1.浏览器必须首先使用[OPTIONS]方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨域请求

2.如果域名在白名单中则在响应结果中告知浏览器允许跨域

3.服务器确认允许之后,才发起实际的 HTTP 请求.在预检请求的返回中,服务器端也可以通知客户端,是否需要携带身份凭证

4.浏览器第二次发送post请求,携带用户登录数据到后端,完成登录验证操作

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值