通过 Node.js 路由 http 请求

Posted

技术标签:

【中文标题】通过 Node.js 路由 http 请求【英文标题】:Routing http requests through Node.js 【发布时间】:2012-07-30 04:25:49 【问题描述】:

我正在尝试使用 Node.js 进行黄瓜测试设置,可以使用 iframe 测试任何网站。 通常,由于跨脚本安全限制,iframe 是不可行的。 但是,如果可能的话(我相信它是。我相信你会想出一个解决方案) 当请求特定的 url 名称时,通过请求的 url 获取作为测试目标的网站,以便 iframe 将加载测试目标的副本。 基本上只是一个标准的 node.js 服务器,它根据 req.url 获取特定页面 类似于地址请求路由器。

这是我公然尝试这样做的。 通过获取测试页。网址有效。 但我在从 http 服务器切换到连接对象时遇到问题。 有没有办法通过 http 服务器响应“提供”连接?

PS。我还使用两个 node.js 服务器创建了一个解决方案。 节点 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 + '...');

【问题讨论】:

【参考方案1】:

毕竟这并不难。 作为 node.js 的新手,我必须意识到使用多个侦听器的可能性。 阅读nodejitsu 的功能帮助我解决了这个问题。

以下示例加载 www.myWebsiteToBeTestedWithCucumberJS.com 指定 url 时如下:http://localhost:9788/myWebsiteToBeTestedWithCucumberJS 所有其他请求都作为 cucumber.js 网站请求处理。 希望这对其他 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.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 (github.com/jbpros/cukestall)。它是 Cucumber.js 潜在的官方“iframe runner”。它旨在测试 local Node.js 应用程序。但是,在 remote 应用程序上运行和加载功能套件应该相当容易。 loadMyWebsiteToBeTestedWithCucumberJS函数名点赞【参考方案2】:
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"); 
); 

【讨论】:

以上是关于通过 Node.js 路由 http 请求的主要内容,如果未能解决你的问题,请参考以下文章

通过http代理执行node js命令

Node.js 路由

Node.js 路由

node.js如何处理请求的路由

Node.js入门教程 第五篇 (Express框架)

Node.js + Express 接口请求(GETPOSTPUT)事例