Search code examples
javascriptfirefoxxmlhttprequestjspsych

xhr posting data on Firefox and page redirection: NS_BINDING_ABORTED


I am trying to code a jsPsych experiment, hosted on a LAMP server. Everything works well; at the end, I am trying to move to the next task by performing a redirection.

Here is the code:

saveData(save_url, data_dir, file_name, extension, redirect_html, redirectToNextPage);

function saveData(save_url, data_dir, file_name, extension, redirect_html, callback) {
    var xhr = new XMLHttpRequest();
    xhr.open('POST', save_url); // 'write_data.php' is the path to the php file used to save the data
    xhr.setRequestHeader('Content-Type', 'application/json');
    xhr.onreadystatechange = function() {
        if (xhr.readyState === XMLHttpRequest.DONE) {
            if (xhr.status === 200) {
                // Data was saved successfully, now trigger the callback function
                callback(redirect_html);
            } else {
                // Handle any errors that occurred during data saving
                console.error('Error saving data: ' + xhr.status);
            }
        }
    };
    xhr.send(JSON.stringify({file_name: file_name, extension: extension, data_dir: data_dir, data: jsPsych.data.get().csv()}));
}

function redirectToNextPage(redirect_html) {

    if((window.location.href).indexOf('?') != -1) {
        var variables = window.location.href.split('?')[1]; 
        redirect_html += "?" + variables;
    };

    last_trial_data = jsPsych.data.getLastTrialData().trials[0];
    if(last_trial_data["chain"] != "false"){
        window.location = redirect_html;
    };  

}

Despite waiting for a confirmation that the data is posted using xhr.readyState === XMLHttpRequest.DONE and xhr.status === 200 before calling the function to perform the redirection, running the experiment on Firefox induces a NS_BINDING_ABORTED error. I understand that what is happening is that the request gets cancelled by the redirection (as running the experiment without the redirection works properly and the data is sent).

Would anyone have an idea of what is going wrong?


Solution

  • We ended up finding a solution that seems to work by calling a Promise, I will leave the code below for posterity:

    function saveData(save_url, data_dir, file_name, extension) {
        return new Promise((resolve, reject) => {
            var xhr = new XMLHttpRequest();
            xhr.open('POST', save_url);
            xhr.setRequestHeader('Content-Type', 'application/json');
            xhr.onreadystatechange = function() {
                if (xhr.readyState === XMLHttpRequest.DONE) {
                    if (xhr.status === 200) {
                        resolve();
                    } else {
                        reject(new Error('Error saving data: ' + xhr.status));
                    }
                }
            };
        xhr.send(JSON.stringify({file_name: file_name, extension: extension, data_dir: data_dir, data: jsPsych.data.get().csv()}));
        });
    }
    
    // Usage of async/await for the redirection
    async function saveAndRedirect(save_url, data_dir, file_name, extension, redirect_html) {
        try {
            await saveData(save_url, data_dir, file_name, extension);
            redirectToNextPage(redirect_html);
        } catch (error) {
            console.error(error);
        }
    }
    
    function redirectToNextPage(redirect_html) {
    
        if((window.location.href).indexOf('?') != -1) {
            var variables = window.location.href.split('?')[1]; 
            redirect_html += "?" + variables;
        };
    
        last_trial_data = jsPsych.data.getLastTrialData().trials[0];
        if(last_trial_data["chain"] != "false"){
            window.location = redirect_html;
        };  
    
    }