नोड में एक सरल HTTP प्रॉक्सी कैसे बनाएं। js?


86

मैं HTTP GETक्लाइंट से किसी थर्ड पार्टी वेबसाइट (Google का कहना है) से अनुरोध पारित करने के लिए एक प्रॉक्सी सर्वर बनाने की कोशिश कर रहा हूं । मेरे प्रॉक्सी को आने वाली रिक्वेस्ट को मिरर करने के लिए टारगेट साइट पर अपने संबंधित पथ को मिरर करने की जरूरत है, इसलिए यदि मेरे क्लाइंट का आग्रह url है:

127.0.0.1/images/srpr/logo11w.png

निम्नलिखित संसाधन परोसा जाना चाहिए:

http://www.google.com/images/srpr/logo11w.png

यहां वह है जो मैंने जुटाया:

http.createServer(onRequest).listen(80);

function onRequest (client_req, client_res) {
    client_req.addListener("end", function() {
        var options = {
            hostname: 'www.google.com',
            port: 80,
            path: client_req.url,
            method: client_req.method
            headers: client_req.headers
        };
        var req=http.request(options, function(res) {
            var body;
            res.on('data', function (chunk) {
                body += chunk;
            });
            res.on('end', function () {
                 client_res.writeHead(res.statusCode, res.headers);
                 client_res.end(body);
            });
        });
        req.end();
    });
}

यह html पृष्ठों के साथ अच्छी तरह से काम करता है, लेकिन अन्य प्रकार की फ़ाइलों के लिए, यह केवल एक रिक्त पृष्ठ या लक्ष्य साइट से कुछ त्रुटि संदेश देता है (जो विभिन्न साइटों में भिन्न होता है)।


1
भले ही जवाब का उपयोग करता है http, उच्च अमूर्त के लिए कम से संबंधित मॉड्यूल के एक आदेश हैं: node, http, connect, expressसे लिया stackoverflow.com/questions/6040012/...
neaumusic

जवाबों:


103

मुझे नहीं लगता कि 3rd पार्टी सर्वर से प्राप्त प्रतिक्रिया को संसाधित करना एक अच्छा विचार है। यह केवल आपके प्रॉक्सी सर्वर की मेमोरी फ़ुटप्रिंट को बढ़ाएगा। इसके अलावा, यही कारण है कि आपका कोड काम नहीं कर रहा है।

इसके बजाय क्लाइंट के माध्यम से प्रतिक्रिया पारित करने का प्रयास करें। निम्नलिखित स्निपेट पर विचार करें:

var http = require('http');

http.createServer(onRequest).listen(3000);

function onRequest(client_req, client_res) {
  console.log('serve: ' + client_req.url);

  var options = {
    hostname: 'www.google.com',
    port: 80,
    path: client_req.url,
    method: client_req.method,
    headers: client_req.headers
  };

  var proxy = http.request(options, function (res) {
    client_res.writeHead(res.statusCode, res.headers)
    res.pipe(client_res, {
      end: true
    });
  });

  client_req.pipe(proxy, {
    end: true
  });
}

1
धन्यवाद, लेकिन बात यह है कि मुझे 3rd पार्टी सर्वर की प्रतिक्रिया को संसाधित करने और / या हेरफेर करने की आवश्यकता है, और फिर इसे अपने क्लाइंट को पास करें। किसी भी विचार कैसे लागू करने के लिए?
नासिर तोरबज़ादे

4
आपको उस मामले में सामग्री-प्रकार के हेडर बनाए रखने की आवश्यकता होगी। HTML डेटा आपके द्वारा बताए गए अनुसार काम करता है क्योंकि text/htmlछवियों / pdfs या किसी भी अन्य सामग्री के लिए सामग्री-प्रकार की चूक , सुनिश्चित करती है कि आप सही डायलर पर पास करें। यदि आप प्रतिक्रियाओं में जो संशोधन लागू करते हैं, उसे साझा करने पर मैं अधिक मदद की पेशकश कर सकूंगा।
vmx

5
क्या आपको प्रॉक्सी मॉड्यूल का उपयोग नहीं करना चाहिए: github.com/nodejitsu/node-http-proxy ?
मैकीज जानकोव्स्की

1
क्या किसी को पता है कि अनुरोध हेडर कैसे रखें?
फिल

1
अच्छा है, लेकिन बहुत सही नहीं है ... यदि रिमोट सर्वर में पुनर्निर्देशन है, तो यह कोड काम नहीं करेगा
जिब्री

30

यहां node-http-proxyनोडजित्सु का उपयोग करके एक कार्यान्वयन किया गया है।

var http = require('http');
var httpProxy = require('http-proxy');
var proxy = httpProxy.createProxyServer({});

http.createServer(function(req, res) {
    proxy.web(req, res, { target: 'http://www.google.com' });
}).listen(3000);

4
मुझे लगता है कि नोड-http-प्रॉक्सी मुख्य रूप से रिवर्स प्रॉक्सी के लिए है ..., बाहरी ग्राहकों से स्थानीय आईपी पर चलने वाले आंतरिक सर्वर और रिवर्स नोड प्रॉक्सी के माध्यम से गैर-मानक पोर्ट जो सार्वजनिक आईपी पते पर मानक बंदरगाहों पर कनेक्शन स्वीकार करता है।
सनी

@ आमिर श्योर, यह उन चीजों में से एक है जो आप इसके साथ कर सकते हैं। यह काफी लचीला है।
बोसगूड सेप

12

यहां एक प्रॉक्सी सर्वर अनुरोध का उपयोग कर रहा है जो रीडायरेक्ट को संभालता है। अपने प्रॉक्सी URL http://domain.com:3000/?url= Isyour_url] को मारकर इसका उपयोग करें

var http = require('http');
var url = require('url');
var request = require('request');

http.createServer(onRequest).listen(3000);

function onRequest(req, res) {

    var queryData = url.parse(req.url, true).query;
    if (queryData.url) {
        request({
            url: queryData.url
        }).on('error', function(e) {
            res.end(e);
        }).pipe(res);
    }
    else {
        res.end("no url found");
    }
}

3
हाय हेनरी, अनुरोध के लिए हेडर कैसे जोड़ें?
केसीएन

लाइन, res.end(e);कारण होगाTypeError [ERR_INVALID_ARG_TYPE]: The "chunk" argument must be of type string or an instance of Buffer. Received an instance of Error
नील डे वेट

6

सुपर सरल और पठनीय, यहां बताया गया है कि कैसे आप केवल Node.js ( v8.1.0 पर परीक्षण ) के साथ एक स्थानीय HTTP सर्वर के लिए एक स्थानीय प्रॉक्सी सर्वर बनाते हैं । मैंने इसे एकीकरण परीक्षण के लिए विशेष रूप से उपयोगी पाया है इसलिए यहाँ मेरा हिस्सा है:

/**
 * Once this is running open your browser and hit http://localhost
 * You'll see that the request hits the proxy and you get the HTML back
 */

'use strict';

const net = require('net');
const http = require('http');

const PROXY_PORT = 80;
const HTTP_SERVER_PORT = 8080;

let proxy = net.createServer(socket => {
    socket.on('data', message => {
        console.log('---PROXY- got message', message.toString());

        let serviceSocket = new net.Socket();

        serviceSocket.connect(HTTP_SERVER_PORT, 'localhost', () => {
            console.log('---PROXY- Sending message to server');
            serviceSocket.write(message);
        });

        serviceSocket.on('data', data => {
            console.log('---PROXY- Receiving message from server', data.toString();
            socket.write(data);
        });
    });
});

let httpServer = http.createServer((req, res) => {
    switch (req.url) {
        case '/':
            res.writeHead(200, {'Content-Type': 'text/html'});
            res.end('<html><body><p>Ciao!</p></body></html>');
            break;
        default:
            res.writeHead(404, {'Content-Type': 'text/plain'});
            res.end('404 Not Found');
    }
});

proxy.listen(PROXY_PORT);
httpServer.listen(HTTP_SERVER_PORT);

https://gist.github.com/fracasula/d15ae925835c636a5672311ef584b999


4

आपका कोड बाइनरी फ़ाइलों के लिए काम नहीं करता है क्योंकि वे डेटा इवेंट हैंडलर में तार नहीं डाल सकते हैं। यदि आपको बाइनरी फ़ाइलों में हेरफेर करने की आवश्यकता है, तो आपको एक बफर का उपयोग करने की आवश्यकता होगी । क्षमा करें, मेरे पास बफर का उपयोग करने का कोई उदाहरण नहीं है क्योंकि मेरे मामले में मुझे HTML फ़ाइलों में हेरफेर करने की आवश्यकता थी। मैं केवल सामग्री प्रकार की जांच करता हूं और फिर पाठ / html फ़ाइलों के लिए उन्हें आवश्यकतानुसार अपडेट करता हूं:

app.get('/*', function(clientRequest, clientResponse) {
  var options = { 
    hostname: 'google.com',
    port: 80, 
    path: clientRequest.url,
    method: 'GET'
  };  

  var googleRequest = http.request(options, function(googleResponse) { 
    var body = ''; 

    if (String(googleResponse.headers['content-type']).indexOf('text/html') !== -1) {
      googleResponse.on('data', function(chunk) {
        body += chunk;
      }); 

      googleResponse.on('end', function() {
        // Make changes to HTML files when they're done being read.
        body = body.replace(/google.com/gi, host + ':' + port);
        body = body.replace(
          /<\/body>/, 
          '<script src="http://localhost:3000/new-script.js" type="text/javascript"></script></body>'
        );

        clientResponse.writeHead(googleResponse.statusCode, googleResponse.headers);
        clientResponse.end(body);
      }); 
    }   
    else {
      googleResponse.pipe(clientResponse, {
        end: true
      }); 
    }   
  }); 

  googleRequest.end();
});    

3

ऊपर माइक के उत्तर का एक और अधिक अनुकूलित संस्करण है जो वेबसाइटों को सामग्री-प्रकार को ठीक से प्राप्त करता है, POST और GET अनुरोध का समर्थन करता है, और आपके ब्राउज़र उपयोगकर्ता-एजेंट का उपयोग करता है ताकि वेबसाइट आपके प्रॉक्सी को एक ब्राउज़र के रूप में पहचान सकें। आप बस URL को बदलकर सेट कर सकते हैं url =और यह मैन्युअल रूप से HTTP और HTTPS सामान को मैन्युअल रूप से करने के बिना सेट करेगा।

var express = require('express')
var app = express()
var https = require('https');
var http = require('http');
const { response } = require('express');


app.use('/', function(clientRequest, clientResponse) {
    var url;
    url = 'https://www.google.com'
    var parsedHost = url.split('/').splice(2).splice(0, 1).join('/')
    var parsedPort;
    var parsedSSL;
    if (url.startsWith('https://')) {
        parsedPort = 443
        parsedSSL = https
    } else if (url.startsWith('http://')) {
        parsedPort = 80
        parsedSSL = http
    }
    var options = { 
      hostname: parsedHost,
      port: parsedPort,
      path: clientRequest.url,
      method: clientRequest.method,
      headers: {
        'User-Agent': clientRequest.headers['user-agent']
      }
    };  
  
    var serverRequest = parsedSSL.request(options, function(serverResponse) { 
      var body = '';   
      if (String(serverResponse.headers['content-type']).indexOf('text/html') !== -1) {
        serverResponse.on('data', function(chunk) {
          body += chunk;
        }); 
  
        serverResponse.on('end', function() {
          // Make changes to HTML files when they're done being read.
          body = body.replace(`example`, `Cat!` );
  
          clientResponse.writeHead(serverResponse.statusCode, serverResponse.headers);
          clientResponse.end(body);
        }); 
      }   
      else {
        serverResponse.pipe(clientResponse, {
          end: true
        }); 
        clientResponse.contentType(serverResponse.headers['content-type'])
      }   
    }); 
  
    serverRequest.end();
  });    


  app.listen(3000)
  console.log('Running on 0.0.0.0:3000')

यहां छवि विवरण दर्ज करें

यहां छवि विवरण दर्ज करें


1

मैंने सिर्फ नोडज में एक प्रॉक्सी लिखी थी जो संदेश के वैकल्पिक डिकोडिंग के साथ HTTPS का ध्यान रखती है। कॉर्पोरेट प्रॉक्सी के माध्यम से जाने के लिए यह प्रॉक्सी प्रॉक्सी-प्रमाणीकरण शीर्षक भी जोड़ सकती है। कॉर्पोरेट प्रॉक्सी के उपयोग को कॉन्फ़िगर करने के लिए आपको प्रॉक्सी.pac फ़ाइल को खोजने के लिए तर्क के रूप में तर्क देने की आवश्यकता है।

https://github.com/luckyrantanplan/proxy-to-proxy-https

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.