What is the best way to construct an AJAX call that includes two sets of POST data?

I'm currently working on a project that involves sending WebGL frames/screenshots to a server for saving to the hard drive and later merging them into a video file. I came across this helpful resource: Exporting video from WebGL

Without delving too much into WebGL specifics, my main goal is to send the content of two client-side JavaScript variables to a localhost node.js server. These variables are:

var frame = frame + 1; //frame counter
var dataUrl = renderer.domElement.toDataURL("image/png"); //encoded screenshot/frame

The receiving server-side code has been provided by Joe Turner (running in node.js). So my question is, how can I send the above variables' content to this node.js script?

var http = require('http');
var querystring = require('querystring');
var fs = require('fs');

// Override to prevent decoding spaces, which may affect base64 encoding
querystring.unescape = function(s, decodeSpaces) {
    return s;
};

// Function to pad numbers according to export format
function pad(num) {
    var s = "000" + num;
    return s.substr(s.length-4);
}

http.createServer(function (request, response) {
    request.content = '';
    request.addListener("data", function(data) {
        request.content += data;
    });

    request.addListener("end", function() {
        if (request.content.trim()) {
            request.content = querystring.parse(request.content);
            var data = unescape(request.content['data']);
            var frame = request.content['frame'];
            // Remove data:image/png;base64,
            data = data.substr(data.indexOf(',') + 1);
            var buffer = new Buffer(data, 'base64');
            fs.writeFile('screen-' + pad(frame) + '.png', buffer.toString('binary'), 'binary');
        }
    });
    response.writeHead(200, {
        'Content-Type': 'text/plain',
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Headers': 'X-Requested-With'
    });
    response.end();
}).listen(8080, "127.0.0.1");

Could implementing something like this work?

...
...
//WebGL related code
...
...
var frame = frame + 1;
var dataUrl = renderer.domElement.toDataURL("image/png");

$.ajax({
    url: "http://127.0.0.1:8080",
    type: "POST",
    data: {"data": dataUrl, "frame": frame}
});
...
...

As an example, you can check out this experiment: Three.js basic example

I made a modification to the code in the experiment mentioned above:

pointLight.position.copy(camera.position);

progress += frameTime;
lastTimestamp = timestamp;
renderer.render(scene, camera);
stats.update();
requestAnimationFrame(animate);

And added this snippet:

pointLight.position.copy(camera.position);

progress += frameTime;
lastTimestamp = timestamp;
renderer.render(scene, camera);
stats.update();
requestAnimationFrame(animate);

var dataUrl = "data:image/png;base64,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#<!---->
var frame = 10;

$.ajax({
    url: "http://127.0.0.1:8080",
    type: "POST",
    data: {"data": dataUrl, "frame": frame}    
});

However, I still cannot locate the saved image file.

Answer №1

Your code is almost there, just remember to include the correct protocol in your URL (don't forget "http://") :

var frame = frame + 1;
var dataUrl = renderer.domElement.toDataURL("image/png");

$.ajax({
        url: "http://127.0.0.1:8080",
        type: "POST",
        data: {"data": dataUrl, "frame": frame}    
});

The server can successfully parse and extract the parameters from your POST request based on the code you shared:

if (request.content.trim()) {    
    request.content = querystring.parse(request.content);
    var data = request.content['data'];
    var frame = request.content['frame'];
    //...

You can access any additional data sent with the POST request using names like this:

request.content['name']

Just ensure that the names match between your client and server side code.

Note that the node.js code receives an escaped base64 string, which needs to be unescaped for the function to work correctly:

data.substr(data.indexOf(',') + 1);

To resolve this issue, apply the built-in node.js function unescape to the data string like so:

var data = unescape(request.content['data']);

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 does the Cluster module in Node.js compare to the Cluster module in Learnboost?

Node.js features its own Cluster core module (source: http://nodejs.org/docs/v0.8.3/api/cluster.html) while Learnboost has introduced a similarly named Cluster module as well (source: , https://github.com/LearnBoost/cluster). What are the differences betw ...

Testing Restful API Endpoints and Code Coverage with Node.js using Mocha

My time in Istanbul has been delightful, and I've been dabbling in different Node.js coverage libraries. However, I'm facing a challenge. Most of my unit tests involve making HTTP calls to my API, like this: it('should update the custom ...

Utilizing Bootstrap Modal functionality in a Django web application to enhance user experience

I am currently facing a minor issue in my Django application. I am attempting to utilize a modal from Bootstrap 4 along with AJAX to create a new object. Below you can view the code I used. However, when the user clicks the button, instead of seeing the mo ...

Application: The initialization event in the electron app is not being triggered

I am facing an issue while trying to run my electron app with TypeScript and webpack. I have a main.ts file along with the compiled main.js file. To troubleshoot, I made some edits to the main.js file to verify if the "ready" function is being called. ...

Troubleshooting inactive CSS hover animation

Greetings! I'm facing an issue with a CSS hover animation. Here are two demos I've created: In the first DEMO, the animation works perfectly. However, in the second DEMO, it doesn't seem to be functioning. On the second demo, there are two ...

Choosing and transferring the table data to be shown in the pop-up box

Having encountered an issue with a popup trigger placed inside a td element, I am seeking advice on how to pass table data into the popup window. Unfortunately, the main popup window was positioned outside the while loop, resulting in multiple instances of ...

Encountering an issue while updating information following the migration to vue-chartjs 4

I recently upgraded from vue-chartjs version 3 to version 4. I successfully migrated my LineChart component by updating the template section and removing the draw method calls. This component is utilized for two separate charts. However, when I close the ...

Retrieve data from a JSON file to assign to a variable, then access another API to retrieve a second

I am completely new to the world of javascript and json. My previous experience with javascript was quite minimal, about 12 years ago. So, please bear with me as I try to explain my current issue. The problem I am facing involves retrieving a second API UR ...

Determining the Clicked Button in React When Multiple Buttons are Present

Within my functional component, I have a table with rows that each contain an edit button. However, when I click on one edit button, changes are applied to all of them simultaneously. How can I identify which specific button was clicked and only apply chan ...

Having trouble rendering to the framebuffer due to issues with the texture

In the process of incorporating shadow maps for shadows, I am attempting to render a scene to a separate framebuffer (texture). Despite my efforts, I have not been able to achieve the desired outcome. After simplifying my codebase, I am left with a set of ...

Discovering a device's model using JavaScript

How can I use Javascript to redirect users to different download pages based on their device model? ...

Is there a foolproof method to authenticate form submissions using Javascript/Ajax instead of relying on PHP?

Currently, my process of handling HTML form submissions is done in PHP where I submit the form to a PHP file that: Verifies against a cookie created at page load to prevent CSRF. Includes a require_once() function for validation purposes. Executes other ...

Using AngularJS to prevent HTML injection in input fields

Is there an effective method to prevent HTML injection in input fields? As an example, if I have a search input field: <input id="search" type="text" ng-model="search" placeholder="search..."> I want to ensure that any attempts to input malicious c ...

What could be causing the returned promise value to not refresh?

I am currently facing an issue with my program. Upon clicking a button, the goal is to update the "likes" attribute of a MongoDB document that has been randomly fetched. Despite setting up the logic for this, the update does not occur as intended: MongoCli ...

Ways to select a single checkbox when other checkboxes are selected in JavaScript

var select_all = document.getElementById("select_all"); //reference to select all checkbox var checkboxes = document.getElementsByName("testc"); //retrieving checkbox items //function to select all checkboxes select_all.addEventListener("change", function ...

Striking a balance between innovation and backward compatibility in the realm of Web Design/Development

Creating websites is my passion, and I enjoy optimizing them for various platforms, devices, and browsers. However, lately, I've been feeling frustrated. I'm tired of facing limitations in implementing my creative ideas due to outdated technolog ...

Vue Router consistently triggers browser reloads, causing the loss of Vuex state

I encountered an issue that initially appeared simple, but has turned out to be more complex for me: After setting up a Vue project using vue-cli with Router, VueX, and PWA functionalities, I defined some routes following the documentation recommendations ...

There seems to be a problem with the full calendar updateEvent feature as it is unable to read the property 'clone'

Struggling to update an event using FullCalendar and a modal. Encounter the 'cannot read property 'clone' of undefined' error when attempting to update. Following the documentation, I utilize the clientEvents method. It is crucial t ...

Exploring the power of ElasticSearch alongside Mysql

As I plan the development of my next app, I am faced with the decision between using NoSQL or a Relational Database. This app will be built using ReactJS and ExpressJS. The data structure includes relational elements like videos with tags and users who li ...

How can Selenium be used to identify an Internet Explorer browser extension?

Can Selenium be used to detect internet explorer browser plugins? For example, if I open a URL on IE and want to check for any installed plugins, is there a way to automate this with selenium? ...