Search code examples
djangopostcookiesxmlhttprequest

Django redirect with message after XMLHttpRequest


I have a template that send a JSON to my backend with a POST XMLHttpRequest with

    var xmlhttp = new XMLHttpRequest();   // new HttpRequest instance 
    var theUrl = "newSeq";
    xmlhttp.open("POST", theUrl);
    xmlhttp.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
    xmlhttp.setRequestHeader("X-CSRFToken", csrftoken);
    xmlhttp.send(JSON.stringify(my_json));

The Django backend manage the request with

def newSeq(request):
    if request.method == "POST":
        print(request.body)
        messages.success(request, "Ricevuto")
        return redirect("newSeq")
    
    return render(
        request,
        'dashboard/newSeq.html',
        {

        }
    )

My issue is that the redirect doesn't work and on the frontend I have the error the cookies "messages" has been rejected because it is already expired

Is there a way to delete the specific cookies and make the page redirect with the correct message?


Solution

  • First of all, I recommend that you replace XMLHttpRequest for the Fetch API. Also, you do not need to mess with Cookies yourself, let the framework take care of it for you with its middlewares.

    The main problem is that you are returning a full HTML page (upon telling the Framework to render dashboard/newSeq.html). In reality you only need to redirect to another view and we can also do that with JavaScript. Here is a simple example:

    views.py

    def fetch_new_seq(request):
        """Attach message and reverse resolve redirection URL"""
        messages.success(request, "Ricevuto")
        redirect_url = reverse('new-seq')
        return JsonResponse({'url': redirect_url})
    

    template.html

    ...
    <script>
        function getCookie(name) {
            ...
        }
    
        async function postData() {
            const url = "http://localhost:8000/fetch/new/seq/"
            const data = {some: "data"}
            const csrftoken = getCookie('csrftoken');
            
            const response = await fetch(url, {
                method: 'POST',
                headers: {
                    'X-CSRFToken': csrftoken,
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(data)
            });
            return await response.json()
        }
        
        postData().then((data) => { 
            window.location.replace(data.url); 
        });
    </script>
    ...