我使用Django编写了一个自定义的CORS中间件
这篇文章是岩手大学 Advent Calendar 2020 的第24天的文章。
首先/一开始
我曾经在个人开发中使用Django创建API。在这个过程中,我遇到了CORS问题,并且需要解决CORS支持的问题。
Django中有一个名为django-cors-headers的东西。然而,我尝试使用django-cors-headers实现,但似乎无法正确指定Access-Control-Allow-Origin,并使请求可以从其他网站发送。因此,我创建了一个Django中间件来实现CORS支持,现在向您介绍一下。
因为我是Django的新手,所以如果有任何错误的地方,请指出来,对我的学习非常有帮助。
实施
实施如下。
from django.http import HttpResponse
from django.utils.deprecation import MiddlewareMixin
class CustomCorsMiddleware(MiddlewareMixin):
def process_request(self, request):
if request.method == 'OPTIONS':
response = HttpResponse()
response['Access-Control-Allow-Origin'] = 'http://localhost:3000' # クライアントのオリジン
response['Access-Control-Allow-Headers'] = ', '.join([ # 許可するHeaderを追加
'Content-Type',
])
response['Access-Control-Allow-Methods'] = ', '.join([ # 許可するリクエストメソッドを追加
'DELETE',
'GET',
'OPTIONS',
'PATCH',
'POST',
'PUT',
])
return response
else:
return None
def process_response(self, request, response):
response['Access-Control-Allow-Origin'] = 'http://localhost:3000' # レスポンスを読み取ることができるオリジン
response['Content-Type'] = 'application/json' # レスポンスタイプ
return response
当请求到达时,process_request方法将被执行,如果返回None,则会执行已路由的视图。
リクエスト
↓
process_request が実行 → 返り値がある場合はその返り値を返す
↓
返り値が None の場合は、リクエストのルーティングに対応する`view`が実行される
在上述代码中,为了应对预检请求,对于OPTIONS方法,我们在响应头中添加允许的源、头部请求方法的信息,并返回该响应。
然后,当进行响应时,process_response方法会在最后执行。
view を実行
↓
process_request が view から返されたレスポンスを受け取り、レスポンスに処理を行う
↓
レスポンス
在上述代码中,使用了常见的CORS。
由于CORS策略的限制,浏览器阻止了从源地址’http://localhost:3000’访问’http://localhost:8000’的XMLHttpRequest请求,因为请求的资源上缺少’Access-Control-Allow-Origin’头部设置。
指定响应的源以读取响应,并且在响应类型中指定application/json。
只需要将这个定制的中间件添加到settings.py中就完成了。
MIDDLEWARE = [
'custom_middlewares.custom_cors_middleware.CustomCorsMiddleware', # 追加
'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',
]
最后
我用Django试了一下,我觉得最让我感受到的是,日本语的文档很少。
也许如果有英语文档可以像日本语一样容易读的话,就能减轻一些困难了。