Django允许Ajax多域名跨域访问

django ajax 2016年12月03日 星期六

进来做的项目,由于前后端分离,前端和后端的域名不一样,造成了需要解决跨域的问题。前端分为用户端和后台管理页面,域名也不相同,同时要支持所有的前端跨域访问,而且还要保证登录的session能够正常的种植到前端。

解决跨域的问题:

支持跨域就是server端在请求的过程中在返回头信息中加上允许跨域的域名,django统一设置返回的response的头信息简洁的方法就是自定义middleware,如下:

class CORSMiddleware(object):
    """
    允许跨域中间件
    """

    def process_request(self, request):

        if 'HTTP_ACCESS_CONTROL_REQUEST_METHOD' in request.META:
            response = HttpResponse()

            # 支持多域名跨域
            if isinstance(settings.ALLOWED_ORIGINS, list):
                for origin in settings.ALLOWED_ORIGINS:
                    if origin == request.META['HTTP_ORIGIN']:
                        response['Access-Control-Allow-Origin'] = origin
                        break
            else:
                response['Access-Control-Allow-Origin'] = settings.ALLOWED_ORIGINS

            response['Access-Control-Allow-Credentials'] = settings.ALLOW_CREDENTIALS
            response['Access-Control-Allow-Methods'] = settings.ALLOWED_METHODS
            response['Access-Control-Allow-Headers'] = settings.ALLOWED_HEADERS
            return response

        return None

    def process_response(self, request, response):
        # Avoid unnecessary work
        if response.has_header('Access-Control-Allow-Origin'):
            return response

        # 支持多域名跨域
        if isinstance(settings.ALLOWED_ORIGINS, list):
            for origin in settings.ALLOWED_ORIGINS:
                if origin == request.META['HTTP_ORIGIN']:
                    response['Access-Control-Allow-Origin'] = origin
                    break
        else:
            response['Access-Control-Allow-Origin'] = settings.ALLOWED_ORIGINS

        response['Access-Control-Allow-Credentials'] = settings.ALLOW_CREDENTIALS
        response['Access-Control-Allow-Methods'] = settings.ALLOWED_METHODS
        response['Access-Control-Allow-Headers'] = settings.ALLOWED_HEADERS
        return response

其中的配置都在django的settings中,这样方便各个环境的调试,如:

# 跨域请求设置
# * 代表支持所有域名跨域,建议开发环境,固定域名支持列表: ['http://irory.me', ]
ALLOWED_ORIGINS = '*'
ALLOW_CREDENTIALS = 'true'
ALLOWED_METHODS = 'POST, GET, OPTIONS, PUT, DELETE'
ALLOWED_HEADERS = 'Origin, X-Requested-With, Content-Type, Accept, X-CSRFToken'

解决Session跨域种植:

在django的settings中设置session种植的域,这样也有一定的安全性。

SESSION_COOKIE_DOMAIN = ".irory.me"