最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Routing http requests through Node.js - Stack Overflow

programmeradmin1浏览0评论

I'm trying to make a cucumber test setup with Node.js that can test any website by using an iframe. Normally the iframe is a no go because of cross script security limitations. However if it was possible (I'm sure it is. And i trust you to e up with a solution) to fetch the website being target for the test via the requested url when a specific url name is being requested, so that the iframe would be loaded with a copy of the test target. Basically just a standard node.js server that fetches specific pages based on the req.url Akin to an Address Request Router.

Here is my blatant attempt to do exactly that. Fetching the test page via. the url works. But i'm having a problem switching from the http server to the connection object. Is there a way to "feed" the connection with the http server response?

PS. i also created a solution with two node.js servers. Node 1 fetched the test target and mixing it with cucumber test page. Node 2 hosting the cucumber test. This solution is working. But it creates problems on websites where javascript naming conflicts occur. Which is why the iframe solution, that solves this problem by encapsulation is more appealing.

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,   
                   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');
                    page = page.replace(/ data-src="\//g     , ' data-src="www.myWebsiteToBeTestedWithCucumberJS');
                    page = page.replace(/ href="\//g         , ' href="www.myWebsiteToBeTestedWithCucumberJS');

                    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 + '...');

I'm trying to make a cucumber test setup with Node.js that can test any website by using an iframe. Normally the iframe is a no go because of cross script security limitations. However if it was possible (I'm sure it is. And i trust you to e up with a solution) to fetch the website being target for the test via the requested url when a specific url name is being requested, so that the iframe would be loaded with a copy of the test target. Basically just a standard node.js server that fetches specific pages based on the req.url Akin to an Address Request Router.

Here is my blatant attempt to do exactly that. Fetching the test page via. the url works. But i'm having a problem switching from the http server to the connection object. Is there a way to "feed" the connection with the http server response?

PS. i also created a solution with two node.js servers. Node 1 fetched the test target and mixing it with cucumber test page. Node 2 hosting the cucumber test. This solution is working. But it creates problems on websites where javascript naming conflicts occur. Which is why the iframe solution, that solves this problem by encapsulation is more appealing.

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.,   
                   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.');
                    page = page.replace(/ data-src="\//g     , ' data-src="www.myWebsiteToBeTestedWithCucumberJS.');
                    page = page.replace(/ href="\//g         , ' href="www.myWebsiteToBeTestedWithCucumberJS.');

                    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 + '...');
Share Improve this question edited Aug 1, 2012 at 12:05 DevNull asked Aug 1, 2012 at 9:34 DevNullDevNull 7635 gold badges17 silver badges30 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 3

Well it wasn't so difficult after all.
Being new to node.js i had to realize the possibilties of using multiple listeners.
Reading on nodejitsu's features helped me solve the problem.

Below example loads www.myWebsiteToBeTestedWithCucumberJS. when specifying the url as follows: http://localhost:9788/myWebsiteToBeTestedWithCucumberJS where all other requests is handled as cucumber.js website requests.
Hope this make sense to other node.js newcucumbers.

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.',   
               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./');
                page = page.replace(/ data-src="\//g     , ' data-src="http://www.myWebsiteToBeTestedWithCucumberJS./');
                page = page.replace(/ href="\//g         , ' href="http://www.myWebsiteToBeTestedWithCucumberJS./');

                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);
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(' Wele to about us page'); 
        res.end(); 
    } 
    else if(url ==='/contact') { 
        res.write(' Wele 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"); 
}); 
发布评论

评论列表(0)

  1. 暂无评论