Django前后端分離跨域請求問題


一、問題背景

  之前使用django+vue進行前后端分離碰到跨域請求問題,跨域(域名或者端口不同)請求問題的本質是由於瀏覽器的同源策略導致的,當請求的響應不是處於同一個域名和端口下,瀏覽器不會接受響應,同源策略也是瀏覽器針對請求的安全問題所作出的一種保護行為。針對跨域問題,可以有下面的解決方式:

  • JSONP方式
  • 自定義中間件,設置響應頭
  • 使用django-cors-headers包

二、解決方式

(一)自定義中間件

  JSONP本質上是利用html的一些不受同源策略影響的標簽屬性src,例如:<a>、<img>、<script>等標簽的src屬性,從而實現跨域請求,但是這種方法只支持GET的請求方式,這里暫不做過多討論,主要說自定義中間件以及利用django-cors-headers包來實現跨域。

1、自定義中間件

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

2、注冊中間件(在settings文件中注冊)

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
     ...
     ...
    'crm.utils.cors.CORSMiddleware' #跨域中間件
]

(二)CORS(Cross-Origin Resource Sharing)

1、安裝django-cors-headers包

pip install django-cors-headers #在對應的開發環境中安裝

2、修改settings文件

  • 注冊應用
# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    ...'django.contrib.staticfiles',
    'corsheaders',#放在新建應用之前
    'rest_framework',
    ...'crm'
]
  • 中間件注冊
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'corsheaders.middleware.CorsMiddleware',  # 注意順序,放在此處
    'django.middleware.common.CommonMiddleware',
     ...
]
  • 其它設置
CORS_ORIGIN_ALLOW_ALL = True  #允許所有的請求,或者設置CORS_ORIGIN_WHITELIST,二選一
CORS_ALLOW_HEADERS = ('*') #允許所有的請求頭
CORS_ALLOW_CREDENTIALS = True  # 允許攜帶cookie,前端需要攜帶cookies訪問后端時,需要設置withCredentials: true

這樣就可以進行跨域使用了。

  但是大多數站點將需要利用Django提供跨站點請求偽造保護CORS和CSRF是分開的,並且Django無法使用您的CORS配置免除網站Referer對安全請求所做檢查。做到這一點的方法是使用其CSRF_TRUSTED_ORIGINS設置

3、CSRF整合

#1、CSRF_TRUSTED_ORIGINS  設置
CORS_ORIGIN_WHITELIST  = [
     ' http://read.only.com '' http://change.allowed.com ',
] #不需要CORS_ORIGIN_ALLOW_ALL=True的設置

CSRF_TRUSTED_ORIGINS  = [
     ' change.allowed.com ',
]

#2、中間件設置
#啟用此功能在django.middleware.csrf.CsrfViewMiddleware后,還應添加#corsheaders.middleware.CorsPostCsrfMiddleware
MIDDLEWARE_CLASSES  = [
     ... 
    ' corsheaders.middleware.CorsMiddleware ',
     ... 
    ' django.middleware.csrf.CsrfViewMiddleware ''corsheaders.middleware.CorsPostCsrfMiddleware ',
     ... 
]

詳情參考官方文檔https://github.com/adamchainz/django-cors-headers

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM