简体   繁体   English

AJAX请求Express.JS中的服务器上的数据显示在客户端中?

[英]AJAX request for data on the server in Express.JS to display in client?

I have been tasked to display this code on the client. 我受命在客户端上显示此代码。 I managed to load data/content on the page but its not so elegant . 我设法在页面上加载了数据/内容,但是它并不那么优雅

 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 foo = 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', {pageID: 'mainData', breaches: breaches, iconList: iconList, sidebar: ['/images/vertbar.jpg'] }); console.log(breaches); console.log(iconList); }); module.exports = router; 

This is the crux of the task. 这是任务的关键。

A friend of yours created a webservice to track these leaks and asked you to create a website to visualize them. 您的一个朋友创建了一个Web服务来跟踪这些泄漏,并要求您创建一个网站以对其进行可视化。

He created two different webservices: 他创建了两个不同的Web服务:

  • 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 / breaches?index = [正整数]-此Web服务返回具有“结果”属性的对象,该对象包含从提供的索引开始的最多20个违规站点的数组(例如,调用/ ws / breaches?index = 0将返回最后20个被破坏的站点,/ ws / breaches?index = 20将返回20个下一个,等等。)-一个被破坏的站点对象包含以下信息:-site:被破坏站点的域-日期:违约,以毫秒为单位-数字:泄漏的帐户数

    • GET /ws/icon?site=[domain of a site] GET / ws / icon?site = [站点域]
      • This webservice returns the url of an icon for the provided site 该Web服务返回所提供站点的图标的URL
      • The icons size is 58x36 pixels 图标大小为58x36像素

I am using the Express and EJS frameworks to do so. 我正在使用ExpressEJS框架。 However I am having a hard time with the following. 但是,我在以下方面遇到了困难。

  1. How to pass the variables, objects from Express.js (the server) to the client. 如何将变量,对象从Express.js(服务器)传递到客户端。

This will get variables, objects etc. to the templates : 这将获取变量,对象等到模板

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

目录结构

I have a js file in my public folder (see image) called contentLoader.js where I guess I should make a AJAX request or something to fetch. 我有一个js文件中我的public文件夹中(见图片)称为contentLoader.js ,我想我应该做一个AJAX请求或东西来获取。 But is that what I should be doing? 但是那是我应该做的吗? Should I be getting the parameters of the ask above here? 我应该在这里获取上面的Ask参数吗?

var xmlhttp = new XMLHttpRequest();
var url = "index";

  xmlhttp.onreadystatechange = function() {
      if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
          var users = JSON.parse(xmlhttp.responseText).breaches;   
          // do something with the users variable that was passed by the routes
          console.log(users);
      }
  };

xmlhttp.open("GET", url, true);
xmlhttp.setRequestHeader('Accept', 'application/json');
xmlhttp.send();

So is my set-up or thinking correct? 那么我的设置或思维是否正确? I know they're many ways to do something. 我知道他们有很多方法可以做某事。 But intuition is telling me I am supposed to use all that server code from the server, rather trying to pass it to a script on the client. 但是直觉告诉我,我应该使用服务器中的所有服务器代码,而不是尝试将其传递给客户端上的脚本。

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 / breaches?index = [正整数] -此Web服务返回具有“结果”属性的对象,该对象包含从提供的索引开始的最多20个违规站点的数组(例如,调用/ ws / breaches?index = 0将返回最后20个被破坏的站点,/ ws / breaches?index = 20将返回20个下一个,等等。)-一个被破坏的站点对象包含以下信息:-site:被破坏站点的域-日期:违约,以毫秒为单位-数字:泄漏的帐户数

If you look at the description, there are key parts (which I have bolded for you). 如果您查看说明,则有一些关键部分(我已为您粗体显示)。 It gives you the request method (GET), the path (/ws/breaches) + query string (?index=[a positive integer]), and the return value (an object). 它为您提供请求方法(GET),路径(/ ws / breaches)+查询字符串(?index = [正整数])和返回值(对象)。

When you set up a route in Express, you must specify the request method (which you have), a path (incorrect), and a response (incorrect). 在Express中设置路由时,必须指定请求方法(具有),路径(不正确)和响应(不正确)。 A response can be in different formats such as plain text, HTML, XML, and JSON. 响应可以采用不同的格式,例如纯文本,HTML,XML和JSON。 The latter is what you would typically use to send back an object. 后者是通常用于发送回对象的东西。 Express have convenient methods such as res.render() , res.send() , res.json() and others to send back response in proper formats. Express具有方便的方法,例如res.render()res.send()res.json()和其他方法,可以以正确的格式发送回响应。 In your case, you would be using the latter res.json() as you want to send back an object. 在您的情况下,您要使用后者的res.json()来发送回一个对象。

In the description, it specifies what the object must contain: it must have a result property which is an array of sites (objects), each containing their own set of properties. 在描述中,它指定了对象必须包含的内容:它必须具有一个result属性,该属性是站点(对象)的数组,每个站点都包含自己的一组属性。

In the description, it also talks about the index which comes from the query string. 在描述中,它还讨论了来自查询字符串的index To access that value, you would use req.query.index . 要访问该值,可以使用req.query.index So when you are building the object, you would need to do something with that value. 因此,在构建对象时,您需要使用该值做一些事情。

router.get('/ws/breaches', function(req, res) {
    // this is just an example of how the object would look;
    // you are most likely going to be building this object dynamically involving req.query.index
    let obj = {
        result: [
            {
                site: 'http://www.somedomain.com',
                date: 243,
                number: 2
            },
            { 
                site: 'http://www.anotherdomain.com',
                date: 312,
                number: 10
            },
            // etc
        ]
    };
    // send the response
    res.json(obj);
});

When it comes to the client code, 关于客户端代码,

var url = "/ws/breaches?index=0"; // example
xmlhttp.onreadystatechange = function() {
    if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
        var result = JSON.parse(xmlhttp.responseText).result;   
        // this should be an array of the sites
        console.log(result);
    }
};

I think you started off well. 我想你起步很好。 As you said, there's no right answer as many people set up their environment differently. 正如您所说,没有正确的答案,因为许多人以不同的方式设置他们的环境。 Though, you probably should create a generic function for making AJAX calls, so that you don't repeat your code everywhere. 但是,您可能应该创建一个通用函数来进行AJAX调用,以免您到处重复代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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