javascript 通过 Node.js 路由 http 请求

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11756459/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 14:13:49  来源:igfitidea点击:

Routing http requests through Node.js

javascriptnode.jsnetworkingcucumber

提问by DevNull

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 come 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.

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

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?

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

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.

附注。我还创建了一个带有两个 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 + '...');

回答by DevNull

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.

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

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

下面的示例在指定 url 时加载 www.myWebsiteToBeTestedWithCucumberJS.com,如下所示:http://localhost:9788/myWebsiteToBeTestedWithCucumberJS其中所有其他请求都被处理为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);

回答by Shashwat Gupta

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"); 
});