IT박스

node.js http.Client에서 http 프록시를 사용하려면 어떻게해야합니까?

itboxs 2020. 7. 4. 11:20
반응형

node.js http.Client에서 http 프록시를 사용하려면 어떻게해야합니까?


standard을 사용하여 node.js에서 나가는 HTTP 호출을 만들고 싶습니다 http.Client. 그러나 네트워크에서 직접 원격 서버에 연결할 수 없으므로 프록시를 거쳐야합니다.

node.js가 프록시를 사용하도록하려면 어떻게해야합니까?


Tim Macfarlane답변 은 HTTP 프록시 사용과 관련하여 가깝습니다.

비보안 요청에 HTTP 프록시를 사용하는 것은 매우 간단합니다. 경로 부분에 전체 URL이 포함되고 호스트 헤더가 연결하려는 호스트로 설정되는 것을 제외하고 프록시에 연결하고 정상적으로 요청합니다.
Tim은 그의 대답에 매우 가까웠지만 호스트 헤더를 올바르게 설정하지 못했습니다.

var http = require("http");

var options = {
  host: "proxy",
  port: 8080,
  path: "http://www.google.com",
  headers: {
    Host: "www.google.com"
  }
};
http.get(options, function(res) {
  console.log(res);
  res.pipe(process.stdout);
});

레코드의 경우 그의 대답은 http://nodejs.org/에서 작동 하지만 서버가 호스트 헤더를 신경 쓰지 않기 때문입니다.


request 를 사용할 수 있습니다 . 방금 하나의 외부 "proxy"매개 변수를 사용하여 node.js에서 프록시를 사용하는 것이 믿을 수 없을 정도로 쉽다는 것을 알았습니다. 더 많은 HTTP 프록시를 통해 HTTPS를 지원합니다.

var request = require('request');

request({
  'url':'https://anysite.you.want/sub/sub',
  'method': "GET",
  'proxy':'http://yourproxy:8087'
},function (error, response, body) {
  if (!error && response.statusCode == 200) {
    console.log(body);
  }
})

https 서버로 프록시를 시도하는 경우에도 'http'를 사용하여 프록시에 액세스하는 데 시간이 걸렸습니다. 이것은 Charles (osx 프로토콜 분석기)를 사용하여 저에게 효과적입니다.

var http = require('http');

http.get ({
    host: '127.0.0.1',
    port: 8888,
    path: 'https://www.google.com/accounts/OAuthGetRequestToken'
}, function (response) {
    console.log (response);
});

여기서 @Renat에서 이미 언급했듯이 프록시 된 HTTP 트래픽은 일반적인 HTTP 요청에서 발생합니다. 목적지 전체 URL 을 경로로 전달하여 프록시에 대해 요청 하십시오.

var http = require ('http');

http.get ({
    host: 'my.proxy.com',
    port: 8080,
    path: 'http://nodejs.org/'
}, function (response) {
    console.log (response);
});

내가 찾은이 모듈을 추가 할 것이라고 생각 했습니다 : https://www.npmjs.org/package/global-tunnel , 그것은 나를 위해 잘 작동했습니다 (아래 코드만으로 모든 코드 및 타사 모듈과 즉시 작업했습니다).

require('global-tunnel').initialize({
  host: '10.0.0.10',
  port: 8080
});

이 작업을 한 번 수행하면 응용 프로그램의 모든 http (및 https)가 프록시를 거치게됩니다.

또는 전화

require('global-tunnel').initialize();

http_proxy환경 변수를 사용합니다


'요청'http 패키지에는 다음 기능이있는 것 같습니다.

https://github.com/mikeal/request

예를 들어, 아래의 'r'요청 객체는 localproxy를 사용하여 요청에 액세스합니다.

var r = request.defaults({'proxy':'http://localproxy.com'})

http.createServer(function (req, resp) {
  if (req.url === '/doodle.png') {
    r.get('http://google.com/doodle.png').pipe(resp)
  }
})

불행히도 "전역"기본값은 없으므로이를 사용하는 lib 사용자는 lib가 http 옵션을 통과하지 않으면 프록시를 수정할 수 없습니다 ...

크리스, HTH


기본적으로 명시적인 프록시 지원이 필요하지 않습니다. 프록시 프로토콜은 매우 간단하며 일반적인 HTTP 프로토콜을 기반으로합니다. HTTPClient와 연결할 때 프록시 호스트와 포트를 사용해야합니다. 예 (node.js 문서에서) :

var http = require('http');
var google = http.createClient(3128, 'your.proxy.host');
var request = google.request('GET', '/',
  {'host': 'www.google.com'});
request.end();
...

기본적으로 프록시에 연결하지만 "http://www.google.com"에 요청하십시오.


프록시 공급자에 대한 기본 인증을 사용해야하는 경우 다음을 사용하십시오.

var http = require("http");

var options = {
    host:       FarmerAdapter.PROXY_HOST,
    port:       FarmerAdapter.PROXY_PORT,
    path:       requestedUrl,
    headers:    {
        'Proxy-Authorization':  'Basic ' + new Buffer(FarmerAdapter.PROXY_USER + ':' + FarmerAdapter.PROXY_PASS).toString('base64')
    }
};

var request = http.request(options, function(response) {
    var chunks = [];
    response.on('data', function(chunk) {
        chunks.push(chunk);
    });
    response.on('end', function() {
        console.log('Response', Buffer.concat(chunks).toString());
    });
});

request.on('error', function(error) {
    console.log(error.message);
});

request.end();

나는 개인 프록시 서버를 샀다.

255.255.255.255 // IP address of proxy server
99999 // port of proxy server
username // authentication username of proxy server
password // authentication password of proxy server

그리고 나는 그것을 사용하고 싶었습니다. 첫 번째 답변두 번째 답변 은 http (proxy)-> http (destination)에서만 작동했지만 http (proxy)-> https (destination)을 원했습니다.

그리고 https 대상의 경우 HTTP 터널을 직접 사용하는 것이 좋습니다 . 여기 에서 해결책을 찾았 습니다 . 최종 코드 :

const http = require('http')
const https = require('https')
const username = 'username'
const password = 'password'
const auth = 'Basic ' + Buffer.from(username + ':' + password).toString('base64')

http.request({
  host: '255.255.255.255', // IP address of proxy server
  port: 99999, // port of proxy server
  method: 'CONNECT',
  path: 'kinopoisk.ru:443', // some destination, add 443 port for https!
  headers: {
    'Proxy-Authorization': auth
  },
}).on('connect', (res, socket) => {
  if (res.statusCode === 200) { // connected to proxy server
    https.get({
      host: 'www.kinopoisk.ru',
      socket: socket, // using a tunnel
      agent: false    // cannot use a default agent
    }, (res) => {
      let chunks = []
      res.on('data', chunk => chunks.push(chunk))
      res.on('end', () => {
        console.log('DONE', Buffer.concat(chunks).toString('utf8'))
      })
    })
  }
}).on('error', (err) => {
  console.error('error', err)
}).end()

Node should support using the http_proxy environmental variable - so it is cross platform and works on system settings rather than requiring a per-application configuration.

Using the provided solutions, I would recommend the following:

Coffeescript

get_url = (url, response) ->
  if process.env.http_proxy?
    match = process.env.http_proxy.match /^(http:\/\/)?([^:\/]+)(:([0-9]+))?/i
    if match
      http.get { host: match[2], port: (if match[4]? then match[4] else 80), path: url }, response
      return
  http.get url, response

Javascript

get_url = function(url, response) {
  var match;
  if (process.env.http_proxy != null) {
    match = process.env.http_proxy.match(/^(http:\/\/)?([^:\/]+)(:([0-9]+))?/i);
    if (match) {
      http.get({
        host: match[2],
        port: (match[4] != null ? match[4] : 80),
        path: url
      }, response);
      return;
    }
  }
  return http.get(url, response);
};

Usage To use the method, effectively just replace http.get, for instance the following writes the index page of google to a file called test.htm:

file = fs.createWriteStream path.resolve(__dirname, "test.htm")
get_url "http://www.google.com.au/", (response) ->
  response.pipe file
  response.on "end", ->
    console.log "complete"

Imskull's answer almost worked for me, but I had to make some changes. The only real change is adding username, password, and setting rejectUnauthorized to false. I couldn't comment so I put this in an answer.

If you run the code it'll get you the titles of the current stories on Hacker News, per this tutorial: http://smalljs.org/package-managers/npm/

var cheerio = require('cheerio');
var request = require('request');

request({
    'url': 'https://news.ycombinator.com/',
    'proxy': 'http://Username:Password@YourProxy:Port/',
    'rejectUnauthorized': false
}, function(error, response, body) {
    if (!error && response.statusCode == 200) {
        if (response.body) {
            var $ = cheerio.load(response.body);
            $('td.title a').each(function() {
                console.log($(this).text());
            });
       }
    } else {
        console.log('Error or status not equal 200.');
    }
});

May not be the exact one-liner you were hoping for but you could have a look at http://github.com/nodejitsu/node-http-proxy as that may shed some light on how you can use your app with http.Client.


http://groups.google.com/group/nodejs/browse_thread/thread/d5aadbcaa00c3f7/12ebf01d7ec415c3?lnk=gst&q=proxy#12ebf01d7ec415c3

Based on the answers from this thread it would seem like you could use proxychains to run node.js through the proxy server:
$ proxychains /path/to/node application.js

Personally I wasnt able to install any of the proxychains versions on Cygwin/Windows environment so couldn't test it.

Furthermore, they also talked about using connect-proxy but I could not find any documentation on how to do this.

In short, I'm still stuck, but maybe someone can use this info to find a suitable work-around.


For using a proxy with https I tried the advice on this website (using dependency https-proxy-agent) and it worked for me:

http://codingmiles.com/node-js-making-https-request-via-proxy/


use 'https-proxy-agent' like this

var HttpsProxyAgent = require('https-proxy-agent');
var proxy = process.env.https_proxy || 'other proxy address';
var agent = new HttpsProxyAgent(proxy);

options = {
    //...
    agent : agent
}

https.get(options, (res)=>{...});

If you have the Basic http authentication scheme you have to make a base64 string of myuser:mypassword, and then add "Basic" in the beginning. That's the value of Proxy-Authorization header, here an example:

var Http = require('http');

var req = Http.request({
    host: 'myproxy.com.zx',
    port: 8080,
    headers:{"Proxy-Authorization": "Basic bXl1c2VyOm15cGFzc3dvcmQ="},
    method: 'GET',
    path: 'http://www.google.com/'
    }, function (res) {
        res.on('data', function (data) {
        console.log(data.toString());
    });
});

req.end();

In nodejs you could use Buffer to encode

var encodedData = Buffer.from('myuser:mypassword').toString('base64');

console.log(encodedData);

Just as example, in browsers you could encode in base64 using btoa(), useful in ajax requests in a browser without proxy settings performing a request using proxy.

var encodedData = btoa('myuser:mypassword')

console.log(encodedData);

How to find wich scheme accepts the proxy server?

If we don't have a custom DNS configured (that would throw something like ERR_NAME_NOT_RESOLVED), when we perform a request, the response (code 407) should inform in the response headers which http authentication scheme the proxy is using.


I think there a better alternative to the answers as of 2019. We can use the global-tunnel-ng package to initialize proxy and not pollute the http or https based code everywhere. So first install global-tunnel-ng package:

npm install global-tunnel-ng

Then change your implementations to initialize proxy if needed as:

const globalTunnel = require('global-tunnel-ng');

globalTunnel.initialize({
  host: 'proxy.host.name.or.ip',
  port: 8080
});

참고URL : https://stackoverflow.com/questions/3862813/how-can-i-use-an-http-proxy-with-node-js-http-client

반응형