简体   繁体   中英

How can I display/get data in a request from a web-service using Express.JS?

I am using Express.JS to create a web application to serve up some data from a two different web-services and present it in a view (I am using EJS to render my templates).

GET /ws/breaches?index=[a positive integer] - This webservice returns an object with a "result" property containing an array of at most 20 breached sites, starting at the provided index (eg calling /ws/breaches?index=0 will return the 20 last breached sites, /ws/breaches?index=20 the 20 next, etc.) - A breached site object contains the following information: - site: The domain of the breached site - date: The time of the breach, in milliseconds - number: The number of accounts leaked

GET /ws/icon?site=[domain of a site] - This webservice returns the url of an icon for the provided site - The icons size is 58x36 pixels

app.js

var express = require('express'),
    reload = require('reload'),
    app = express();

app.set('port', process.env.PORT || 8888);

app.use(require('./routes/index'));
app.use(express.static('app/public'))

app.set('view engine', 'ejs');
app.set('views', 'app/views');

var server = app.listen(app.get('port'), function(){
    console.log('Listening on port ' + app.get('port'));
});

reload(server, app);

module.exports = app;

index.js

var express = require('express');
    router = express.Router(),
    connect = require('connect'),
    urlParse = require('url').parse,
    fs = require('fs');

var iconList = fs.readFileSync('app/data/icons.list').toString().split('\n').filter(function(site){
    return site;
});

var random = function(max){
    return Math.floor(Math.random() * max);
};

var icon2Site = function(icon){
    var site = icon.replace(/_/g,'.').replace(/\.png$/,'');
    return site;
};

var breaches = [];

// breaches generation
(function(){
    for(var i =0; i< 1000; i++){
        var index = random(iconList.length);
        breaches.push({
            site : icon2Site(iconList[index]),
            date : Date.now() - 432000000 + random(432000000),
            number : random(100000)
        });
    }
})();

breaches.sort(function(a,b){
    return a.date - b.date;
});

var jsonResponse = function(res, code, body){
    res.writeHead(code, {
        'Content-Type' : 'application/json',
        'Content-Length' : Buffer.byteLength(body)
    });
    res.end(body);
};

var server = connect()
    .use(connect.logger('dev'))
    .use(function(req,res,next){
        req.parsedUrl = urlParse(req.url, true);
        next();
    })
    .use(function(req,res,next){
        if(req.parsedUrl.pathname !== '/ws/breaches'){
            return next();
        }
        var index = parseInt(req.parsedUrl.query.index, 10) || 0;
        jsonResponse(res,200,JSON.stringify({
            result : breaches.slice(index, index + 20)
        }));
    })
    .use(function(req,res,next){
        if(req.parsedUrl.pathname !== '/ws/icon'){
            return next();
        }
        var site = req.parsedUrl.query.site || "";
        console.log(req.parsedUrl.query.site);
        site = site.replace(/\./g,'_') + ".png";
        jsonResponse(res,200,JSON.stringify({
            result : "https://s3-eu-west-1.amazonaws.com/static-icons/" + site
        }));
    })
    .use(connect.static(__dirname + '/public', {
        maxAge : 1000 * 60 * 5 // Five minutes of cache
    }));


router.get('/', function(req, res) {
  res.render('index', {server : server, sidebar:['/images/vertbar.jpg']} );
  console.log(breaches);
});

module.exports = router;

index.ejs

<div class="col-xs-12 col-sm-8 col-md-9 col-lg-9 right-column-augment">
  <ul>
    <% /* %> <% for(var i=0; i<tbd.length;i++){%> <% */ %>
      <li><img src="<%= sidebar %>"></li>
    <% /* %> <%}%> <% */ %>
  </ul>
 </div>

Essentially I am unclear how to expose these functions to my routes so I can eventually render in my templates.

Thanks in advance!

Just execute all of the logic of your functions inside the route, then store result in some object, and pass it to EJS view

Example to passing breaches array to your breaches(.ejs) view:

    var breaches = [];

// breaches generation
(function(){
    for(var i =0; i< 1000; i++){
        var index = random(iconList.length);
        breaches.push({
            site : icon2Site(iconList[index]),
            date : Date.now() - 432000000 + random(432000000),
            number : random(100000)
        });
    }
})();

breaches.sort(function(a,b){
    return a.date - b.date;
}); 

res.render('breaches', { breaches: breaches });
    return;

In this example, you are adding breaches to your array, then you are sorting then you are passing them to your view called breaches(.ejs)

Then you can loop through them in your breaches(.ejs) view:

    <div class="col-xs-12 col-sm-8 col-md-9 col-lg-9 right-column-augment">
  <ul>
   <% for(var i = 0; i < breaches.length; i++){ %>
      <li><%= breaches[i].site %></li>
   <% } %>
  </ul>
 </div>

So, it looks like you want to fetch that data client side via ajax. All index.ejs is doing is building an html response on your server, and passing that to the browser. Since all of this is happening on your server, it doesn't make sense (and isn't possible) to make http requests from your view (index.ejs) to get that data. You could fetch that data in your "router.get('/', function(req, res) {" function and pass the result as variables to your view like you are doing with the sidebar var, but that doesn't seem to be what you are asking for.

To answer your specific question, what you want to do is - once the html gets to the browser, you'll want to make a call to those two endpoints and update the dom with javascript. There are many ways to do that. For simplicity sake, you could add a script tag under your div that, on page load ( Javascript that executes after page load ) makes an ajax request ( How to make an AJAX call without jQuery? ) to /ws/breaches?index=[a positive integer] and /ws/icon?site=[domain of a site] and updates the dom with the results ( https://www.w3schools.com/js/js_htmldom_html.asp )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM