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

Please do not post screen images of code here. Copy/paste the code into your message. (I can’t quote sections of code from an image.)

Now, what is the specific line(s) of code where you’re submitting data to the view?

What precisely is the data you are submitting? (Show me in the code, what the data is that you are submitting in your AJAX call.)

Hi.

The following source code is the form I have where I am trying to find a way to submit the JavaScript variable called “data”:

<div class="contentarea">
        <form method="POST" action="{% url 'analyze-facial-image' %}">
            {% csrf_token %}
            <h1 align="center">Facial Image Recognition</h1>

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

            <!--An id on a <button> tag assigns an identifier to the button.
                The id allows JavaScript to easily access the <button> element
                and manipulate it.-->
            <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>

            <!--The following button will trigger the JavaScript function.-->
            <button id="sendButton">Submit Facial Image</button>
        </form>
    </div>

The following is the JavaScript source code that involves the AJAX call:

var data;

    (function() {

        // We will scale the photo width to this.
        var width = 500;
        // The height will be computed based on the input stream.
        var height = 0;

        var streaming = false;

        var video = null;
        var canvas = null;
        var photo = null;
        var startbutton = null;

        function startup() {
            video = document.getElementById('video');
            canvas = document.getElementById('canvas');
            photo = document.getElementById('photo');

            /*The following line is executed when a user clicks on the
              "Capture Image" button.

              document.getElementById returns the element whose 'id'
              is 'startbutton'.*/
            startbutton = document.getElementById('startbutton');

            // Access the video stream from the webcam.
            navigator.mediaDevices.getUserMedia({
                video: true,
                audio: false
            })
            // Upon success, stream video in a video tag.
            .then(function(stream) {
                video.srcObject = stream;
                video.play();
            })
            .catch(function(err) {
                console.log("An error occurred: " + err);
            });

            video.addEventListener('canplay', function(ev) {
                if (!streaming) {
                    height = video.videoHeight / (video.videoWidth / width);

                    if (isNaN(height)) {
                        height = width / (4 / 3);
                    }

                    video.setAttribute('width', width);
                    video.setAttribute('height', height);
                    canvas.setAttribute('width', width);
                    canvas.setAttribute('height', height);
                    streaming = true;
                }
            }, false);

            startbutton.addEventListener('click', function(ev) {
                takepicture();
                ev.preventDefault();
            }, false);

            clearphoto();
        }

        /*Collect the frames of the photo from the canvas and then
          convert it into a PNG format, so that it can be shown in
          the HTML page.*/
        function clearphoto() {
            var context = canvas.getContext('2d');
            context.fillStyle = "#AAA";
            context.fillRect(0, 0, canvas.width, canvas.height);

            var data = canvas.toDataURL('image/png');

            photo.setAttribute('src', data);
        }

        /*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.
                  
                  'data' will hold the URL link of each image that is
                  captured from the camera.*/
                data = canvas.toDataURL('image/png');

                /*'src' is the name of the attribute whose value is to be set.
                  'data' 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', data);

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

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

            }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' %}";

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

    /*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();
        });
    });

    // let SendFacialImage = document.getElementById("sendButton");

    // SendFacialImage.addEventListener('click', event => {
    //     SendFacialImage();
    // });

As you can see, I am trying to use the function called SendFacialImage() to submit the JavaScript variable called “data” as a POST request to Django’s server.

Then I want to be able to access this variable “data” from a Django view called “AnalyzeFacialImage()”.

Sorry if my approach is wrong.

Yes, I’m asking you to identify the one line of code that is responsible for actually sending the data to the server.

After understanding your point, I have created a new form for this which is the following inside facial-login.html:

<html>
<body>
        <form name = "form" action = "{% url 'facial-image' %}" method = "POST">
            {% 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>

            <input type="hidden" id="facialImage" name="facialImage">

            <button type="submit" onclick="GetImageURL()">Submit Facial Image</button>
        </form>

<script>
var data = 2;

function GetImageURL() {
    document.getElementById("facialImage").value = data;
}
</script>
</body>
</html>

With this source code, can I expect the form element “facialImage” to have a value of 2 and be properly submitted when I submit this form?

I have included action = “{% url ‘facial-image’ %}” because I want to send this data to a particular view that will handle this data.

Please let me know if you have seen my latest reply. Thank you Mr. Whitesell!

I have. But you keep working on your form (that I’ve explained is not being used) when I’m trying to keep you focused on the JavaScript.

I would like for you to identify the one line of JavaScript code that actually submits the data to the view.

Unfortunately, I don’t think I have a line of code in the JavaScript section that submits the variable ‘data’ to the desired Django view.

Can JavaScript actually submit a variable to a Django view? Is this the easiest way of doing it in my case? (In my case I am trying to send the JavaScript variable ‘data’ to the Django view AnalyzeFacialImage().)

<script>
    var data;

    (function() {

        // We will scale the photo width to this.
        var width = 500;
        // The height will be computed based on the input stream.
        var height = 0;

        var streaming = false;

        var video = null;
        var canvas = null;
        var photo = null;
        var startbutton = null;

        function startup() {
            video = document.getElementById('video');
            canvas = document.getElementById('canvas');
            photo = document.getElementById('photo');

            /*The following line is executed when a user clicks on the
              "Capture Image" button.

              document.getElementById returns the element whose 'id'
              is 'startbutton'.*/
            startbutton = document.getElementById('startbutton');

            // Access the video stream from the webcam.
            navigator.mediaDevices.getUserMedia({
                video: true,
                audio: false
            })
            // Upon success, stream video in a video tag.
            .then(function(stream) {
                video.srcObject = stream;
                video.play();
            })
            .catch(function(err) {
                console.log("An error occurred: " + err);
            });

            video.addEventListener('canplay', function(ev) {
                if (!streaming) {
                    height = video.videoHeight / (video.videoWidth / width);

                    if (isNaN(height)) {
                        height = width / (4 / 3);
                    }

                    video.setAttribute('width', width);
                    video.setAttribute('height', height);
                    canvas.setAttribute('width', width);
                    canvas.setAttribute('height', height);
                    streaming = true;
                }
            }, false);

            startbutton.addEventListener('click', function(ev) {
                takepicture();
                ev.preventDefault();
            }, false);

            clearphoto();
        }

        /*Collect the frames of the photo from the canvas and then
          convert it into a PNG format, so that it can be shown in
          the HTML page.*/
        function clearphoto() {
            var context = canvas.getContext('2d');
            context.fillStyle = "#AAA";
            context.fillRect(0, 0, canvas.width, canvas.height);

            var data = canvas.toDataURL('image/png');

            photo.setAttribute('src', data);
        }

        /*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.
                  
                  'data' will hold the URL link of each image that is
                  captured from the camera.*/
                data = canvas.toDataURL('image/png');

                /*'src' is the name of the attribute whose value is to be set.
                  'data' 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', data);

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

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

            }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' %}";

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

    /*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 = data;
    }
    </script>

You have a line of code that issues an http request to a url.

That url is a reference to a view.

The contents of that http request is the data being supplied to the view.

That’s how the browser communicates with views - regardless of whether it’s a simple page request issued by the browser itself or an AJAX request issued by JavaScript.

So break the process down - you’re displaying a form with a button. That button is suppposed to cause something to happen (It’s supposed to submit an image to a view by passing that image as data within an http request to a url).

Rather than just quoting the entire block of code, you should be able to identify what each line of code is doing.

  • What code executes when the button is pressed?

  • What one line of code issues the http request to the desired url?

I believe you are referring to the following source code right?

var URL = "{% url 'facial-login-result' %}";

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

You’re in the right area, yes. So which one line of code is responsible for sending the request?

I believe that the following line of code is responsible for issuing the HTTP request to the URL:

        $.post(URL, facialImage, function(response){

        }

Aren’t I correct in doing this?

Correct!

Now, your use of the $.post function leads me to believe you’re using jQuery. Is that correct?

If so, the docs for it are located at jQuery.post() | jQuery API Documentation

The next questions are, what data then are you sending to the server? (Which parameter in the post call?) And where is that variable defined in the code?

Yes, I am trying to use jQuery to send a JavaScript variable to a Django view.

I am trying to send the following data to the server:
var facialImage = {'data': data};

The ‘data’ variable contains the URL of a facial image.

So as the code below demonstrates, I am attempting to send the variable ‘facialImage’
to the server.

The parameter in the post call that is being sent to the server is called “facialImage”.

I am defining the variable “facialImage” inside the SendFacialImage() function which I want to be activated when the “Submit Facial Image” button is clicked. I do not believe it is a problem if this variable is locally declared because it is being assigned a value from a global variable.

However, why is this not working correctly when I click on the “Submit Facial Image” button?

How can I see if the “facialImage” variable successfully made it to the AnalyzeFacialImage view?

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

Good!

Notice that you’re sending “data” to the server.

You’re only sending “data” to the server.

So, notice what you’re not sending.

You’re not sending the form.

You’re not sending any of the data associated with the form.

This brings us back to the issue you raised at:

with the response addressing it at:

And the details about what you need to do is at: Cross Site Request Forgery protection | Django documentation | Django

Right. Does this mean that I would need to send the entire form by passing the name of the form (“form”) as a parameter to the $.post() function like the following?

$.post(URL, form, function(response){
            if(response === 'success')
            { 
                alert('Facial Image Successfully Sent!'); 
            }
            else{ 
                alert('Error Sending Facial Image!'); 
            }
        });

If I send the entire form, wouldn’t I still need to include the variable ‘data’ as a parameter to the $.post() function as ‘data’ is not present in the form?

As far as the csrf_token is concerned. Could I simply do the following in the JavaScript section?

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

And then add ‘csrfmiddlewaretoken’ as a parameter to the $.post() function as the following demonstrates?

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

Whether you need to include the form in what you send is up to you. But you’re sending one object, one that you have named “facialImage”. Anything being sent by this line:
$.post(URL, facialImage, function(response){
needs to be a member of that object.

The docs referenced above describe what you need to do for the csrf token data, and the different variances that may exist depending upon your specific situation.

Is it necessary to have the entire form as a parameter in the $.post() function if I am just sending one variable to the AnalyzeFacialImage() view function? I would think not?

You are correct, it is not necessary. You only need to put the data you need into the object being sent.

What I am stuck on is simply accessing the variable called “facialImage” inside the view function with something like the "var facialImageURL = requst.POST[“facialImage”] because “facialImage” is only a variable inside the JavaScript section of the HTML page and is not an HTML element.

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!'); 
            }
        });
    }

I am attempting to retrieve the variable in the view with the following way:
HTML Code

<form  name = "form">
    Username: <input type="text" name="user">
</form>

View

def view_name(request):
    var username = request.POST["user"]

    dict = { 
        'username': username,
    }
    return render(request, 'validate.html', dict)

I understand that this way will not work because I am making a POST request in the JavaScript. How can I access the “facialImage” variable that is being sent in the JavaScript $.post() request?

First, you really need to stop worrying about your form. It is not part of this process. It has nothing to do with what you’re trying to accomplish here - at least the way you’re trying to do it. There is nothing you’re doing with your form that in any way is helping you.

But beside that, from what I’ve seen, you’re not to that point yet.

If you’re still getting the 403 from a csrf-related issue, your view isn’t being executed.

You’re not going to get anything in the view until that is resolved.

Once you get past that point, then you need to process that request as an AJAX request and not an HTML form submission.

You do this by accessing the submitted JSON using the request.body attribute.

For example, something like:

def my_view(request):
    json_data = json.loads(request.body)