一、跨域出现原因
浏览器的同源策略:同源策略是一种浏览器最基本的安全机制,如果两个 URL 的 protocol、port (如果有指定的话)和 host 都相同的话,则这两个 URL 是同源。
二、解决方案
(一)CORS:使用django-cors-headers包
支持Python 3.6至3.9。
支持Django 2.2到3.2。
1、从pip安装:
pip install django-cors-headers
2、修改settings.py:
- 注册App
INSTALLED_APPS = [
...
'django.contrib.staticfiles',
'corsheaders', # 放在新建应用前
'app01',
...
]
- 注册中间件
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'corsheaders.middleware.CorsMiddleware', # 注意位置
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
...
]
- 其他配置
在Django设置中配置中间件的行为。必须至少设置以下三个之一:
- CORS_ALLOWED_ORIGINS
- CORS_ALLOWED_ORIGIN_REGEXES
- CORS_ALLOW_ALL_ORIGINS
CORS_ALLOWED_ORIGINS:授权进行跨站点HTTP请求的来源列表,默认为[]。
格式为URI+主机名+端口
CORS_ALLOWED_ORIGINS = [
“ https://example.com” ,
“ https://sub.example.com” ,
“ http:// localhost:8080” ,
“ http://127.0.0.1:9000”
]
之前版本,此设置称为CORS_ORIGIN_WHITELIST,该设置仍用作别名,新名称优先。
CORS_ALLOWED_ORIGIN_REGEXES:表示正则表达式的字符串列表,与被授权发出跨站点HTTP请求的Origins相匹配。默认为[]。
当 CORS_ALLOWED_ORIGINS不可行时很有用。
CORS_ALLOWED_ORIGIN_REGEXES = [
r “ ^ https:// \ w + \ .example \ .com $” ,
]
之前版本,此设置称为CORS_ORIGIN_REGEX_WHITELIST,该设置仍用作别名,新名称优先。
CORS_ALLOW_ALL_ORIGINS:如果为True,则将允许所有原点。限制允许的原点的其他设置将被忽略。默认为False。
之前版本,此设置称为CORS_ORIGIN_ALLOW_ALL,该设置仍用作别名,新名称优先。
- 可选设置
CORS_URLS_REGEX:正则表达式,用于限制将为其发送CORS标头的URL。
CORS_URLS_REGEX = r '^ / api /.*$'
CORS_ALLOW_METHODS:实际请求所允许的HTTP动词列表。
CORS_ALLOW_METHODS = [
'DELETE' ,
'GET' ,
'OPTIONS' ,
'PATCH' ,
'POST' ,
'PUT' ,
]
CORS_ALLOW_HEADERS:发出实际请求时可以使用的非标准HTTP标头的列表。
CORS_ALLOW_HEADERS = [
''accept' ,
'accept-encoding' ,
'authorization' ,
'content-type' ,
'dnt' ,
'origin' ,
'user-agent' ,
'x-csrftoken' ,
'x-requested-with' ,
]
- CSRF整合
1、CSRF_TRUSTED_ORIGINS设置
CORS_ALLOWED_ORIGINS = [
'http://read.only.com' ,
'http://change.allowed.com' ,
]
CSRF_TRUSTED_ORIGINS = [
'change.allowed.com' ,
]
2、中间件设置:
MIDDLEWARE_CLASSES = [
...
'corsheaders.middleware.CorsMiddleware' ,
...
'django.middleware.csrf.CsrfViewMiddleware' ,
'corsheaders.middleware.CorsPostCsrfMiddleware' ,
...
]
(二)自定义中间件
# cors.py
"""解决跨域问题的中间件,作用全局"""
class MiddlewareMixin(object):
def __init__(self, get_response=None):
self.get_response = get_response
super(MiddlewareMixin, self).__init__()
def __call__(self, request):
response = None
if hasattr(self, 'process_request'):
response = self.process_request(request)
if not response:
response = self.get_response(request)
if hasattr(self, 'process_response'):
response = self.process_response(request, response)
return response
class CORSMiddleware(MiddlewareMixin):
def process_response(self, request, response):
# 添加响应头
# 限制哪些域名可以访问,用逗号分隔,如果全部可使用'*'
response['Access-Control-Allow-Origin'] = '*'
# 限制携带的请求头,用逗号分隔
response['Access-Control-Allow-Headers'] = 'Content-Type'
# 允许发送的请求方式
response['Access-Control-Allow-Methods'] = 'DELETE, PUT'
return response
在settings注册中间件
MIDDLEWARE = [
...
'app01.cors.CORSMiddleware',
...
]