0

When you have certain javascript functions that you would like to run on the server side whether it be for performance or to hide proprietary code, how would you send and receive the data with AJAX requests when your HTML file accesses external CSS and Javascript files?

For example, what would be the correct way of moving the function "secret_calculation" into index.js (the node.js file)

index.js

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

http.createServer(function (req, res) {

    fs.readFile('app.html', function (err, data) {
        if (err)
        {
            console.log(err);
        }
        res.writeHead(200, {'Content-Type': 'text/html'});
        res.write(data);
        res.end();
    });

    fs.readFile('app.css', function (err, data) {
        if (err)
        {
            console.log(err);
        }
        res.writeHead(200, {'Content-Type': 'text/css'});
        res.write(data);
        res.end();
    });

    fs.readFile('app.js', function (err, data){
        if (err)
        {
            console.log(err);
        }
        res.writeHead(200, {'Content-Type': 'text/javascript'});
        res.write(data);
        res.end();
    });

}).listen(8000);

app.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="app.css">
  </head>

  <body>
    <input id="in_put" type="text" maxlength="3" size="5" oninput="this.value = this.value.replace(/[^0-9]/g, '');" >
    <span> x 5 = </span><span id="answer"></span>
    <br><br>
    <input type="button" id="button1" value="Calculate">

    <script src="app.js"></script>
  </body>
</html>

app.css

span
{
    color: red;
}

app.js

document.getElementById("button1").addEventListener("click", get_input);

function get_input()
{
    user_input = parseInt(document.getElementById("in_put").value);
    user_input = user_input || 0;
    ans = document.getElementById("answer");

    ans.innerHTML = secret_calculation(user_input);
}

function secret_calculation(num)
{
    var result = num * 5;    

    return result;
}

I've found a good example with node.js AJAX requests here, however the article doesn't use external css and javascript files

2 Answers 2

1

One way of doing that would be to run a second http server serving these functions as services (something like a rest API).

For the sake of simplicity I'll use express (to put it simply a wrapper around an http server):

var http = require('http');
var fs = require('fs');
var express = require('express');
var bodyParser from 'body-parser';

// this is server code and won't get to the client if not required
function secret_calculation(num) {
    var result = num * 5;    

    return result;
}
http.createServer(function (req, res) {

    fs.readFile('app.html', function (err, data) {
        if (err) {
            console.log(err);
        }
        res.writeHead(200, {'Content-Type': 'text/html'});
        res.write(data);
        res.end();
    });

    fs.readFile('app.css', function (err, data) {
        if (err) {
            console.log(err);
        }
        res.writeHead(200, {'Content-Type': 'text/css'});
        res.write(data);
        res.end();
    });

    fs.readFile('app.js', function (err, data){
        if (err) {
            console.log(err);
        }
        res.writeHead(200, {'Content-Type': 'text/javascript'});
        res.write(data);
        res.end();
    });

}).listen(8000);

var apiApp = express();

// to be able to use request.body for complex parameters
apiApp.use(bodyParser.json());
apiApp.use(function (req, res, next) {
    // to restrict api calls to the ones coming from your website
    res.append('Access-Control-Allow-Origin', <url of your domain, with port>);
    res.append('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
    res.append('Access-Control-Allow-Headers', 'Content-Type');
    next();
});
//the list of routes your API will respond to, it is better to move this code in another file as it can be huge
apiApp.get('/secret_calculation/:number', function(req, res) {
    var num = parseInt(req.params.number, 10);
    var result = secret_calculation(num);
    res.send(JSON.stringify(result)); 
});
// define as much routes as you want like the model above, using apiApp.post if you want to post data and retrieve it with req.body...etc

// run the API server like your http server above
apiApp.listen(8001, function (err) {
    if (err) {
        return console.error(err);
    }
    console.info(`apiApp listening at ${<url to your domain, without port>}:${8001}`);
});

Then in your application you will be able to retrieve the value from secret_calculation by calling (using fetch, but any other ajax lib will do):

function get_input() {
    const init = {
        'GET', // or POST if you want to POST data
        headers: { 'Content-Type': 'application/json', 'Accept-Encoding': 'identity' },
        cache: 'default',
        // body: data && JSON.stringify(data), if you want to POST data through request body

    };
    var user_input = parseInt(document.getElementById("in_put").value);
    user_input = user_input || 0;
    fetch('/secret_calculation/' + user_input, init)
        .then( function(response) {

            var ans = document.getElementById("answer");
            ans.innerHTML = response;
        })
        .catch ( function(error) {
            console.log('something bad happened:', error);
        });
}

Express js reference

Simple tutorial to create a REST API in 5 minutes with express (similar to the above

Sign up to request clarification or add additional context in comments.

Comments

1

Using express, you can bind a route with GET verb and get a response on the client-side. For example:

index.js

const express = require('express');
const app = express();

app.get('/your-route-here', (req, res) => {
 res.send({response: req.query.num * 5});
});

app.js

let calculatedSecret;
fetch('/your-route-here')
  .then(({data}) => {
    calculatedSecret = data.response;
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.