Passing A JavaScript Variable In An HTML File To A Django View Function

Which form is useless in this case? The form I have in the HTML or the form I have in the JavaScript?

Please let me know when you get a chance Mr. Whitesell.

Hi Mr. Whitesell.

After reading what you have said, I have come to the conclusion that the form which is useless in this case is the following one:

<form name = "form">
            {% csrf_token %}
            <h1 align="center">Facial Image Recognition</h1>

            <div class="camera">
                <video id="video">Video stream not available.</video>
            </div>

            <button id="startbutton">Capture Image</button>

            <!--The HTML canvas tag is where the image frames are stored
                before they are converted into an image of proper format
                to be shown using the <img> tag.-->
            <canvas id="canvas"></canvas>

            <div class="output">
                <img id="photo" alt="The image captured will appear in this box.">
            </div>

            <button id="sendButton">Submit Facial Image</button>            
        </form>

If this is the case, should it I remove the <form> tags around it?

I have also come to the conclusion that I need to focus more on the following:

var URL = "{% url 'facial-login-result' %}";
    csrfmiddlewaretoken = $('input[name=csrfmiddlewaretoken]').val();

    /*POST the data (the facial image) to the server via AJAX.*/
    function SendFacialImage() {
        var facialImage = {'data': data};
        $.post(URL, facialImage, csrfmiddlewaretoken, function(response){
            if(response === 'success')
            { 
                alert('Facial Image Successfully Sent!'); 
            }
            else{ 
                alert('Error Sending Facial Image!'); 
            }
        });
    }

However, if you look at the code directly above, you can see that I have indeed included the csrf middleware token as a parameter in $.post().

The following is what I see in the terminal when clicking the “Submit Facial Image” button:

"GET /facial-login/?csrfmiddlewaretoken=vy9bMAJ240Z7OEIKgdMRwwwcziNaDSuzJ6fAUetxqhjwnvsHuXh2h4DlmVfSf8ld HTTP/1.1" 200 9744

Have I not resolved the issue with the csrf middleware token? Wouldn’t I see an error regarding this in the terminal if this was the case?

Mr. Whitesell, I also wanted to wish you a happy birthday! Let us raise our glasses to your health, happiness, and success in achieving your objectives!

When you get a chance Mr. Whitesell, please let me know. Thank you.

All the details are in the prior posts of this thread, starting at about message 32.

Okay. I will re-read our messages.

Good morning Mr. Whitesell. I have re-read all of our messages starting from message 32 and am trying my best to understand.

Let’s clear up a few things please.

I am using a jQuery post() function to send a JavaScript variable to a Django view with the following function inside the facial-login.html file:

function SendFacialImage() {
        var facialImage = {'data': data};
        $.post(URL, facialImage, csrfmiddlewaretoken, function(response){
            if(response === 'success')
            { 
                alert('Facial Image Successfully Sent!'); 
            }
            else{ 
                alert('Error Sending Facial Image!'); 
            }
        });
    }

If this is the case, then can I remove the <form></form> tags around the following code which is in the same file called facial-login.html? I don’t see why I need them if I am not actually submitting a form. May I remove them in this case?

<form name = "form">
            {% csrf_token %}
            <h1 align="center">Facial Image Recognition</h1>

            <div class="camera">
                <video id="video">Video stream not available.</video>
            </div>

            <button id="startbutton">Capture Image</button>

            <canvas id="canvas"></canvas>

            <div class="output">
                <img id="photo" alt="The image captured will appear in this box.">
            </div>

            <button id="sendButton">Submit Facial Image</button>            
        </form>

Secondly, when I click on the “Submit Facial Image” button, I do not seem to be seeing any issues with the csrf token. The following is how the terminal looks:

[20/Jul/2022 06:26:30] "GET /facial-login/?csrfmiddlewaretoken=9xBQHzYGsvgKuqWMS7x25NGnWtM5tiTZn5HfPdIbOMA93hGJ6R2dQlNwJ6eN5yKD HTTP/1.1" 200 9316

And I don’t see any issues regarding the csrf token in the console after clicking the “Submit Facial Image” button.

Here is the csrf middleware token I have as the third parameter in the $.post() function:

csrfmiddlewaretoken = $('input[name=csrfmiddlewaretoken]').val();

After considering all of this, why do you think the csrf middleware token is still causing issues?

Please let me know Mr. Whitesell. I really appreciate your guidance with this as I am trying to learn.

Reread the documentation on the jQuery post method.

What parameters does it take?

Yes, I have done so.

I noticed that I was getting an error when hitting line 245 in the following code because on the terminal I saw “Entered FacialLoginResult View”, but did not see “Entered 246” which tells me that I never hit that line.

def FacialLoginResult(request):
    if request.method == 'POST':
        print("Entered FacialLoginResult View")
        # All of the data in a POST request will be stored inside
        # the 'POST' dictionary.

        # facialImageURL = request.POST["parameter_name"]

        json_data = json.loads(request.body)
        print("Entered 246")

        # context = json_data["data"]
        print("Entered 249")

    # https://pythonguides.com/django-get-all-data-from-post-request/

        # context = {
        #     'facialImageUrl': facialImageURL,
        # }

        return render(request, 'FacialLoginResult.html')

The following is how I am making the ajax POST request:

$.ajax({
            url : URL,
            type: "POST",
            data : {
                csrfmiddlewaretoken: document.getElementsByName('csrfmiddlewaretoken')[0].value,
                facialImage,
            },
            dataType : "json",
            /*https://stackoverflow.com/questions/8614947/jquery-and-django-csrf-token*/
            /*"success" is what happens when the server responds successfully
              'response' is the response from the Django view (a json object).*/
            success: function(response){
                // $(".sendButton").
            }
        });

What is causing the json_data = json.loads(request.body) line to generate an error?

The csrf middleware token is included properly, so that should not be the issue.

Yep, you’re definitely past that point. Your view wouldn’t be executed if you weren’t handling that correctly.

I’d suggest printing request.body to see what is being seen by the view.

You can also look at the network tab in your browser to see what is being sent to verify that it all is valid json.

Thank you for the feedback Mr. Whitesell.

Follow-up thought on this - what I’d be concerned about is the nature of the data in the image. If it is binary data, it cannot be converted directly to JSON. You’ll want to convert it to base64 in the browser so that it can be sent in the data object and then converted back to the original format in the view.

I am seeing the following inside request.body:

It continues like this all the way until the following:

Interesting. The call is submitting that object as post form data and not json.
But yes, I see in the most recent snippet you’ve posted, you’re showing a $.ajax call with dataType json.

Can you post the complete JavaScript that you’re currently using? (Not any of the css or html, just the JavaScript.)

There’s something else going on here that I’m not seeing.

Below when I used document.write(facialImage); inside the takepicture() function, I was able to see the correct URL for the image that had been taken as a snapshot from the camera.

/*Capture a frame from the video stream.*/
        function takepicture() {
            var context = canvas.getContext('2d');
            if (width && height) {
                canvas.width = width;
                canvas.height = height;

                /*The canvas takes a snapshot of the video.*/
                context.drawImage(video, 0, 0, width, height);

                /*toDataURL('image/png') returns a data URL containing a
                  representation of the image in PNG format.
                  
                  'facialImage' will hold the URL link of each image that is
                  captured from the camera.*/
                facialImage = canvas.toDataURL('image/png');

                /*'src' is the name of the attribute whose value is to be set.
                  'facialImage' is a string containing the value to assign to the attribute.
                  
                  The data is fed as a source of the image element.*/
                photo.setAttribute('src', facialImage);

                // let facialImageURL = '<img src="'+facialImage+'"/>';

                // document.write('<img src="'+facialImage+'"/>');

                // 'facialImage' holds the URL of the image taken from the camera.
                // document.write(facialImage);

            }else {
                clearphoto();
            }
        }

        /*The following code will call the startup() function when
          the HTML page is loaded.*/
        window.addEventListener('load', startup, false);
    })();

    var URL = "{% url 'facial-login-result' %}";
    csrfmiddlewaretoken = $('input[name=csrfmiddlewaretoken]').val();

    /*POST the data (the facial image) to the server via AJAX.*/
    function SendFacialImage() {
        // var facialImage = {'facialImage': facialImage};
        // $.post(URL, facialImage,
        
        //     {csrfmiddlewaretoken: document.getElementsByName('csrfmiddlewaretoken')[0].value}, 
            
        //     function(response) {
        //         if(response === 'success')
        //         { 
        //             alert('Facial Image Successfully Sent!'); 
        //         }
        //         else{ 
        //             alert('Error Sending Facial Image!'); 
        //         }
        //     }
        // );

        $.ajax({
            url : URL,
            type: "POST",
            data : {
                csrfmiddlewaretoken: document.getElementsByName('csrfmiddlewaretoken')[0].value,
                facialImage,
            },
            dataType : "json",
            /*https://stackoverflow.com/questions/8614947/jquery-and-django-csrf-token*/
            /*"success" is what happens when the server responds successfully
              'response' is the response from the Django view (a json object).*/
            success: function(response){
                // $(".sendButton").
            }
        });
    }

    /*A page can't be manipulated safely until the document is "ready." 
      jQuery detects this state of readiness for you. Code included inside 
      $( document ).ready() will only run once the page Document Object Model
      (DOM) is ready for JavaScript code to execute.*/
    $(document).ready(function(){
        $("#sendButton").click(function(){
            SendFacialImage();
        });
    });

    function GetImageURL() {
        document.getElementById("imageURL").value = facialImage;
    }

Ok, it looks like the AJAX call will not convert the data object to json for you, you need to do it yourself.

Try data: JSON.stringify({...}) instead of data: {...} and add the parameter processData: false after it.

The only issue I have is doing it the following way causes the terminal to display Forbidden (CSRF token missing.): /facial-login-result/ whereas before the terminal did not say this.

The following is what I have done:

$.ajax({
            url : URL,
            type: "POST",
            data: JSON.stringify({
                    csrfmiddlewaretoken: document.getElementsByName('csrfmiddlewaretoken')[0].value,

                /*Use stringify() method to convert 'facialImage' into a string,
                  so that it can be sent to the server.*/
                // facialImage: JSON.stringify(facialImage),
                    facialImage,
                }),

            processData: false,
            dataType : "json",
            /*https://stackoverflow.com/questions/8614947/jquery-and-django-csrf-token*/
            /*"success" is what happens when the server responds successfully
              'response' is the response from the Django view (a json object).*/
            success: function(response){
                // $(".sendButton").
            }
        });

Perhaps the csrf middleware token is in the wrong place?

In the terminal, I can still see the csrf middleware token being generated as evident in the following image:

I will again refer you to the Django docs at Cross Site Request Forgery protection | Django documentation | Django.