通过Node.js路由HTTP请求

5
我正在尝试使用Node.js建立一个黄瓜测试设置,可以通过使用iframe来测试任何网站。 通常情况下,由于跨脚本安全限制,iframe是不可行的。 然而,如果可能的话(我相信它是可能的。我相信你会想出一个解决方案), 当请求特定的URL名称时通过请求的URL获取被测试网站,以便用测试目标的副本加载iframe。 基本上只是一个基于req.url获取特定页面的标准node.js服务器,类似于地址请求路由器。
这是我明目张胆地尝试做到这一点的方式。 通过url获取测试页有效。 但是我遇到了从http服务器切换到连接对象的问题。 有没有办法将http服务器响应“馈送”给连接?
另外,我还创建了一个使用两个Node.js服务器的解决方案。 Node 1获取测试目标并将其与黄瓜测试页面混合。 节点2托管黄瓜测试。 该解决方案有效。但它会在JavaScript命名冲突发生的网站上产生问题。 因此,更具吸引力的是通过封装解决此问题的iframe解决方案。
var http  = require('http');
var connect    = require('connect');
var port  = process.env.PORT || 8788;

var server = http.createServer(function(req, webres)
{
    var url = req.url;
    console.log(url);

    if(url == '/myWebsiteToBeTestedWithCucumberJS')
    {
        // Load the web site to be tested "myWebsiteToBeTestedWithCucumberJS"
            // And update the references
            // Finaly write the page with the webres
            // The page will appear to be hosted locally

        console.log('Loading myWebsiteToBeTestedWithCucumberJS');
        webres.writeHead(200, {'content-type': 'text/html, level=1'});
        var options =
        {  
                   host: 'www.myWebsiteToBeTestedWithCucumberJS.com,   
                   port: 80,   
                   path: '/'
        };

        var page = '';
        var req = http.get(options, function(res)
        {
            console.log("Got response: " + res.statusCode);   
            res.on('data', function(chunk)
            {
                page = page + chunk;
            });   
            res.on('end', function()
            {
                    // Change relative paths to absolute (actual web location where images, javascript and stylesheets is placed)
                    page = page.replace(/ href="\/\//g       , ' href="/');
                    page = page.replace(/ src="\//g          , ' src="www.myWebsiteToBeTestedWithCucumberJS.com');
                    page = page.replace(/ data-src="\//g     , ' data-src="www.myWebsiteToBeTestedWithCucumberJS.com');
                    page = page.replace(/ href="\//g         , ' href="www.myWebsiteToBeTestedWithCucumberJS.com');

                    webres.write(page);
                    webres.end('');
            });
        });
    }
    else
    {
        // Load any file from localhost:8788
            // This is where the cucumber.js project files are hosted
        var dirserver     = connect.createServer();
        var browserify = require('browserify');
        var cukeBundle = browserify({
          mount: '/cucumber.js',
          require: ['cucumber-html', './lib/cucumber', 'gherkin/lib/gherkin/lexer/en'],
          ignore: ['./cucumber/cli', 'connect']
        });
        dirserver.use(connect.static(__dirname));
        dirserver.use(cukeBundle);
        dirserver.listen(port);
    }
}).on('error', function(e)
{  
      console.log("Got error: " + e.message);   
});
server.listen(port);
console.log('Accepting connections on port ' + port + '...');
2个回答

3

其实这并不难。
作为一个新手,我必须认识到可以使用多个监听器。
阅读nodejitsu的特性帮助我解决了问题。

以下示例会在URL指定为http://localhost:9788/myWebsiteToBeTestedWithCucumberJS时加载www.myWebsiteToBeTestedWithCucumberJS.com网站, 而所有其他请求均处理为cucumber.js网站请求。
希望这对其他node.js新手有所帮助。

var http  = require('http');

var connect    = require('connect');
var port  = process.env.PORT || 9788;

var server = http.createServer(function(req, webres)
{
    var url = req.url;
    console.log(url);
    if(url == '/myWebsiteToBeTestedWithCucumberJS')
    {
        loadMyWebsiteToBeTestedWithCucumberJS(req, webres);
    }
    else
    {
        loadLocal(req, webres, url);
    }
}).on('error', function(e)
{  
      console.log("Got error: " + e.message);   
});
server.listen(port);
console.log('Accepting connections on port ' + port + '...');

function loadMyWebsiteToBeTestedWithCucumberJS(req, webres)
{
    console.log('Loading myWebsiteToBeTestedWithCucumberJS');
    webres.writeHead(200, {'content-type': 'text/html, level=1'});
    var options =
    {  
               host: 'www.myWebsiteToBeTestedWithCucumberJS.com',   
               port: 80,   
               path: '/'
    };

    var page = '';
    var req = http.get(options, function(res)
    {
        console.log("Got response: " + res.statusCode);   
        res.on('data', function(chunk)
        {
            page = page + chunk;
        });   
        res.on('end', function()
        {
                page = page.replace(/ href="\/\//g       , ' href="/');
                page = page.replace(/ src="\//g          , ' src="http://www.myWebsiteToBeTestedWithCucumberJS.com/');
                page = page.replace(/ data-src="\//g     , ' data-src="http://www.myWebsiteToBeTestedWithCucumberJS.com/');
                page = page.replace(/ href="\//g         , ' href="http://www.myWebsiteToBeTestedWithCucumberJS.com/');

                webres.write(page);
                webres.end('');
        });
    });

}

function loadLocal(req, webres, path)
{
    console.log('Loading localhost');
    webres.writeHead(200, {'content-type': 'text/html, level=1'});
    var options =
    {  
               host: 'localhost',   
               port: 9787,   
               path: path
    };

    var page = '';
    var req = http.get(options, function(res)
    {
        console.log("Got response: " + res.statusCode);   
        res.on('data', function(chunk)
        {
            page = page + chunk;
        });   
        res.on('end', function()
        {
                webres.write(page);
                webres.end('');
        });
    });
}


// Cucumber site listening on port 9787
var dirserver     = connect.createServer();
var browserify = require('browserify');
var cukeBundle = browserify(
{
    mount: '/cucumber.js',
    require: ['cucumber-html', './lib/cucumber', 'gherkin/lib/gherkin/lexer/en'],
    ignore: ['./cucumber/cli', 'connect']
});
dirserver.use(connect.static(__dirname));
dirserver.use(cukeBundle);
dirserver.listen(9787);

顺便提一下,我可以建议您查看Cukestall(https://github.com/jbpros/cukestall)。它是Cucumber.js的潜在官方“iframe runner”。它旨在测试本地Node.js应用程序。但是,在远程应用程序上运行和加载功能套件应该相当容易。 - jbpros
为loadMyWebsiteToBeTestedWithCucumberJS函数名称点个赞。 - NiCk Newman

1
var http = require('http'); 

// Create a server object 
http.createServer(function (req, res) { 

    // http header 
    res.writeHead(200, {'Content-Type': 'text/html'}); 

    var url = req.url; 

    if(url ==='/about') { 
        res.write(' Welcome to about us page'); 
        res.end(); 
    } 
    else if(url ==='/contact') { 
        res.write(' Welcome to contact us page'); 
        res.end(); 
    } 
    else { 
        res.write('Hello World!'); 
        res.end(); 
    } 
}).listen(3000, function() { 

    // The server object listens on port 3000 
    console.log("server start at port 3000"); 
}); 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接