Question

I want to add a X-Frame-Options header to Django CreateView. I need this because I'll be serving a form that will be loaded in iframe tags.

The problem is, there are several methods in django class-based views that return HttpResponse objects. Is there a way to add the header to the responses without overwriting all those methods?

class MyView(CreateView):
    def get(self, request, *args, **kwargs):
        resp = super(MyView, self).get(request, *args, **kwargs)
        resp['X-Frame-Options'] = ''
        return resp
    # Same would go for form_invalid, post, put, etc...
Was it helpful?

Solution

Okay, I fixed it. If you've encountered similar problem, here's how to do it. You have to overwrite render_to_response method in same way I did with get in the example code above.

OTHER TIPS

I tried the overwrite render to response method, but I wanted a solution that I could use for a whole chunk of urls mapped to several views, and not have to deal with overwriting the same method on several views.

I made a middleware class based off of django-cors-headers so I could allow iframe-ing of part of my django app. I keep a middleware.py in my main project directory and save a couple random middleware classes I have made there, like this one here and a ForceResponse Exception for example.

import re
from django import http
from django.conf import settings

class XFrameAllowMiddleware(object):

    def process_request(self, request):
        """
        If CORS preflight header, then create an
        empty body response (200 OK) and return it

        Django won't bother calling any other request
        view/exception middleware along with the requested view;
        it will call any response middlewares
        """
        if (self.is_enabled(request) and
                request.method == 'OPTIONS' and
                "HTTP_ACCESS_CONTROL_REQUEST_METHOD" in request.META):
            response = http.HttpResponse()
            return response
        return None

    def process_response(self, request, response):
        if self.is_enabled(request):
            response['X-Frame-Options'] = 'ALLOWALL'
        return response

    def is_enabled(self, request):
        return re.match(settings.XFRAME_URLS_REGEX, request.path)

Add it to your MIDDLEWARE_CLASSES and configure the regex in your settings:

MIDDLEWARE_CLASSES = (
    ...
    'your_django_app.middleware.XFrameAllowMiddleware',
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    ...
)

XFRAME_URLS_REGEX = r'^/iframe_this_url/.*$'

from the django-cors-headers read.me:

CORS_URLS_REGEX: specify a URL regex for which to enable the sending of CORS headers; Useful when you only want to enable CORS for specific URLs, e. g. for a REST API under /api/. Example:

CORS_URLS_REGEX = r'^/api/.*$'

Default:

CORS_URLS_REGEX = '^.*$'
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top