What could be causing the res.sendfile() method to fail when invoked through a jQuery ajax call?

Problem: The first ajax call in the main.js is functioning correctly, but there seems to be an issue with the second one. Although it appears to be working initially, I suspect that there may be a bug present. Upon clicking the button, I am able to access the getProducts method. However, the content of the product_list.html file does not display on the browser screen as expected. No error messages are displayed on either the front-end or the back-end.

My observation: When I click the button and navigate to F12 -> Network -> products, I notice a status code 200 indicating success along with the content of the product_list.html file in the response.

If the POST ajax call is successful and the line

location.href = "/products";
is added, the browser will load the product_list.html. I am using the GET ajax call because I need to include the jwt token in the request header. (I have omitted the jwt authentication parts from the code below because I believe the issue lies within the relationship between $.ajax() and res.sendFile())

//routes.js

routes.get("/products", ProductController.getProducts);

//ProductController.js

var root = path.join(__dirname, '../../views');
module.exports = {
    getProducts(req, res){
        console.log("getProducts!");                 //This log appears
        res.sendFile("product_list.html", {root})   //HTML is not rendered
    },
}

//main.js

$("#btn-login").click(function(){
    $.ajax({
        type: 'POST',
        url: "http://localhost:8000/login",
        dataType: "json",
        contentType: "application/json",
        data: JSON.stringify({
            "username": $("#login-user").val(),
            "password": $("#login-pwd").val(),
        }),
        success: function(data){
            if ($("#login-chkbx").is(':checked')){
                    $.ajax({
                        url: "http://localhost:8000/products",
                        type: 'GET',
                        beforeSend: function (xhr) {
                            xhr.setRequestHeader("user", localStorage.getItem("user"));
                        },
                    });
                }
            }else{
                console.log("Checkbox is not checked");
            }
        }
    });
});

What is causing this issue and how can it be resolved?

Thank you!

Answer №1

The file needs to be displayed on the browser screen.

However, it should not just appear there automatically. Instead, the file should be sent back to the AJAX function call in the success callback like this:

$.ajax({
    url: "http://localhost:8000/products",
    type: 'GET',
    beforeSend: function (xhr) {
        xhr.setRequestHeader("user", localStorage.getItem("user"));
    },
    success: function (file) {
        // The file is now stored in the "file" variable.
        // You can then manipulate it however you need. For example, replacing
        // the current page with the returned file:

        document.body.innerHTML = file;
    }
});

This is the core concept of AJAX - giving programmers the ability to control how HTTP responses are handled and loaded onto the browser page. If it gives you the freedom to prevent automatic loading of responses, it also means that by default it will not load them - because doing so would negate the purpose of allowing that level of customization.

If your goal is to have responses automatically loaded, then AJAX might not be the best tool for the job:

// Instead of using $.ajax(..., use:
window.location.href = "http://localhost:8000/products";

However, keep in mind that this alternative method does not provide the option to set custom request headers.

Answer №2

When it comes to your frontend implementation, you seem to be disregarding the response from the GET /products call.

Regarding the backend functionality of sendfile, it essentially transfers the file to the requester without any modifications. However, since it is an ajax request, the frontend code needs to handle how the response is displayed.

To ensure the response is rendered properly, consider adding something similar to

success: response =>  $('body').html(response)

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How can I extract only certain keys from a large JavaScript object while keeping the code concise?

Simply put, I aim to streamline objects by discarding unnecessary keys. Imagine a scenario where a third party API sends back JSON data with numerous attributes that hold no importance to you. obj = { name: ..., id: ..., description: ..., blah: .. ...

Unit testing tips: the art of mocking a wrapper function

Unit testing is a new concept for me and I'm currently trying to learn how to stub a wrapper function in Sinon/Mocha. For example, if I have a function like: const user = await User.findOne({ email: email }); I've been successful in stubbing it ...

Display a dialogue box when encountering a Vuetify error. Only open the dialogue box under certain conditions

I am currently implementing vuetify into my project. The main issue I am facing is related to the dialog component, which I only want to open in case of an error. The scenario involves a button calling a backend service to save a product in the database, a ...

Provide details on the final parameters

After creating my discord.js bot, I had the idea to implement a translator feature. To achieve this, I need to extract the last argument from incoming messages. client.on("message", async (message, args) => { if (message.content.startsWith(` ...

Unload pre-loaded JavaScript documents

Two javascript files are included in a popup (simple div) created using ajax. <script type="text/javascript" src="<?php echo JS ?>pm.js"></script> <script type="text/javascript" src="<?php echo JS ?>chat.js"></script> ...

Exploring request parameters within an Express router

I'm currently facing an issue with accessing request parameters in my express router. In my server.js file, I have the following setup: app.use('/user/:id/profile', require('./routes/profile')); Within my ./routes/profile.js fil ...

Converting a JavaScript variable into an xls or csv file

My application currently uses Javascript for calculations and data plotting, but I want to give users the ability to download the data as a csv or xls file. Is there a way in Javascript or another method where users can click a button, enter a filename, an ...

Tips for Developing Drag Attribute Directive in Angular 2.0

Currently, I am referencing the Angular documentation to create an attribute directive for drag functionality. However, it seems that the ondrag event is not functioning as expected. Interestingly, the mouseenter and mouseleave events are working fine ac ...

Denied access to retrieve JSON data from URL due to the Content Security Policy directive 'connect-src'

I'm facing an issue while trying to make an AJAX call to a local API. Strangely, it works with cURL and on the same server, just using a different URL. Connection refused to '' due to a Content Security Policy violation: "default-sr ...

Exploring Facebook Graph API response with Angular 2 Mapping

I am using HTTP calls to access the Graph API in order to retrieve posts from a Facebook page. Here is the code snippet that fetches an array of posts: let url = 'https://graph.facebook.com/15087023444/posts?fields=likes.limit(0).summary(true),comme ...

What is the best way to extract the text from the first visible `<td></td>` table row using jQuery?

In this particular scenario, there is a table included: <table id="table"> <thead> <tr> <th>Name</th> <th>Course</th> </tr> </thead> <tbody> <tr style="display:none"> ...

Mastering the art of knowing when to implement asynchronous and synchronous programming techniques is essential for

As I explore asynchronous programming in JavaScript, I am faced with the challenge of integrating two email providers: Sendgrid and Mailgun. My goal is to send an email using one provider, and if any errors occur during the process, automatically resend th ...

Failure to recognize AJAX content in .ready function

When using an AJAX call to load content, primarily images, I encountered a challenge. I wanted the div to fade in only after all the images were fully loaded. To achieve this, I made use of .ready method in jQuery. However, it seemed like the images were n ...

Issue: angular2-cookies/core.js file could not be found in my Angular2 ASP.NET Core application

After spending 2 hours searching for the source of my error, I have decided to seek help here. The error message I am encountering is: "angular2-cookies/core.js not found" I have already installed angular2-cookie correctly using npm. Below is the code ...

Enhancing Form Fields Dynamically using AJAX and JSON

I'm trying to update specific fields in my form after fetching data from a database using AJAX and JSON. Here is the code snippet: In my form: <div class="form"> <?php $form=$this->beginWidget('CActiveForm', array( ' ...

Select the first item that is visible and chosen

Currently, I am working with a select list: <option ng-repeat="hour in Hours" value="{{hour.Value}}" ng-show="filterEvent($index)" ng-selected="hour.Value == EventDate || $first"> {{hour.Text}} </opti ...

Leveraging npm packages in Meteor's Angular 1.3 framework

Although it may sound like a silly question, I am still confused. It has been said that Meteor has native support for npm modules in version 1.3. I am currently using Meteor with Angular integration. From the tutorial, it appears that using npm modules sh ...

The vue-croppa component is showing unusual behavior, with an error message stating "Failed to mount component: template or render function not

I recently tried utilizing vue-croppa for image cropping in my project. I installed it using the npm package manager with the command: npm install --save vue-croppa However, when attempting to implement it as usual: import Croppa from 'vue-croppa&a ...

Updating the background of a button with Vue JS by utilizing an object upon clicking

If you have three buttons and want to change the background color when clicked, for example, clicking on the red button should turn the background color red. However, there is an important detail here: if you click on one button and then another, the old c ...

Customize time formatting in Angular to accommodate localized time formats

I am utilizing Angular's localization service version 8.3.28 to support English, Spanish (Mexico) with code es-MX, and Spanish (Spain) with code es-SP While using the date pipe: {{ foo.Date | date: 'shortDate' }} The dates are changing to ...