7.Django如何实现跨域

文章目录

    • 1.同源策略
    • 2.简单/复杂请求
    • 3.CORS
    • 4.如何解决跨域
      • 方法一:添加响应头Access-Control-Allow-Origin
      • 方法二:使用扩展django-cors-headers
    • 5.跨域实现流程

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>app2title>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js">script>

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

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

').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请求,携带用户登录数据到后端,完成登录验证操作

你可能感兴趣的:(DRF,http,前端,https)