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


137

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

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


1
같은 문제가 있습니다. Node.js가 방화벽 뒤에 있으며 외부 웹 사이트에 HTTPClient를 만들 수 없습니다.
ddallala

답변:


153

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/에서 작동 하지만 서버가 호스트 헤더를 신경 쓰지 않기 때문입니다.


1
http 프록시 연결 https 포트를 사용하는 방법이 있습니까? 쉬운 방법이없는 것 같습니다
Gohan

@Gohan http 프록시를 통해 https 서버에 연결하는 방법에 대한 예는 아래 Chris의 답변을 참조하십시오.
HairOfTheDog

잘못된 요청을 받으면 경로를 입력하십시오. '/'
Laurent Debricon

9
옵션 블록에 프록시 사용자와 프록시 비밀번호를 통합하려면 어떻게해야합니까?
Twistleton

이것이 바뀌 었습니까? 최종 목적지가 다른 로컬 서버 인 경우 404
에도을

53

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

1
모두 근무 http하고 https감사합니다, 내 경우에는 많은
사무엘 무사

내부 법인 페이지에서 이것이 작동하지 않는 이유가 있습니까?
keinabel

1
내부 회사 페이지가 프록시 뒤에 있다는 것이 놀랍습니다. 내부 페이지에 프록시가 무시되지 않습니까? 다른 vlan에 있습니까?
Chanoch

U는 어떻게 든 인증을 지정해야합니다 (내가 알아 낸 경우 여기에 게시)
Igor L.

프록시와 함께 요청을 사용하여이 오류가 발생했습니다. 오류 : 터널링 소켓을 설정할 수 없습니다. 원인 = connect ECONNREFUSED 127.0.0.1:80
Federico Caccia

35

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

1
위의 코드는 저에게 효과적이지 않으며 github.com/joyent/node/issues/2474 문제와 관련하여 koichik의 답변을 확인하십시오 "method": "connect"및 "connect"이벤트를 사용해야합니다. 경로 정보를 보냈습니다. .
Palani

16

여기서 @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);
});

2
이것은 Fiddler가 프록시를 통한 적절한 HTTP 요청이 아니라고 제안하는 프로토콜 위반이라고
Marc

11

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환경 변수를 사용합니다


2
이것은 나를 위해 일했다! 실제로이 방법으로 코드에서 프록시를 분리하고 npm의 기존 구성을 사용합니다! 그것이 내가 갈 것이라고 말하는 방법입니다
cesaregb

@NeelBasu 그렇습니다
major-mann

10

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

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
      path: '/your/url'  // specify path to get from server
    }, (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()

7

'요청'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


request http 패키지를 사용하면 코드가 프록시 사용과 프록시 사용이 아닌 것을 쉽게 전환 할 수 있습니다 (노트북에서 매우 유용함).
Jon Madison

5

기본적으로 명시적인 프록시 지원이 필요하지 않습니다. 프록시 프로토콜은 매우 단순하며 일반적인 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"에 요청하십시오.


3
http.createClient는 더 이상 사용되지 않으며 Tim Macfarlane은 아래의 최신 http.get을 사용합니다
sami

1
이것은 createClient 가 제거되어 v5.6부터 node.js에서 더 이상 작동하지 않을 것입니다 .
Marc

5

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

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();

1
"FarmerAdapter"는 어디에서 찾을 수 있습니까?
Alex

3

노드는 http_proxy 환경 변수 사용을 지원해야합니다. 따라서 플랫폼 간이며 응용 프로그램 별 구성이 아닌 시스템 설정에서 작동합니다.

제공된 솔루션을 사용하여 다음을 권장합니다.

커피 스크립트

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

자바 스크립트

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

사용법 이 메소드를 사용하려면 http.get을 대체하면됩니다. 예를 들어 다음은 google의 색인 페이지를 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"

http_proxy를 설정해도 Windows에서 노드를 실행할 때 영향을 미치지 않습니다.
EricLaw

Windows (즉, 내가 사용하는 기본 시스템)에서 작동해야합니다. 터미널 세션을 재설정 한 설정을 설정 한 후 (제어판을 통해 설정하고 설정하지 않은 경우) 확인하십시오. echo % HTTP_PROXY %를 사용하여 올바르게 설정되었는지 확인할 수 있어야합니다. 또는 노드 자체를 사용하는 것이 좋습니다. -e "console.log (process.env.http_proxy);" 이것은 Windows에서 저에게 효과적이므로 행운을 빕니다.
Luke

1

Imskull의 답변은 거의 효과가 있었지만 약간 변경해야했습니다. 유일한 변경 사항은 사용자 이름, 비밀번호를 추가하고 rejectUnauthorized를 false로 설정하는 것입니다. 나는 논평 할 수 없으므로 이것을 대답에 넣었다.

코드를 실행하면이 자습서에 따라 Hacker News의 최신 기사 제목을 얻을 수 있습니다. 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.');
    }
});

1

생각이 우리가 사용할 수있는 2019 년의 같은 답변에 더 나은 대안 global-tunnel-ng프록시 초기화 패키지를하고 오염되지 http또는 https사방 기반 코드를. 먼저 global-tunnel-ng패키지를 설치하십시오 .

npm install global-tunnel-ng

그런 다음 필요한 경우 구현을 변경하여 프록시를 초기화하십시오.

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

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


0

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

이 스레드의 답변을 기반으로 프록시 체인 을 사용 하여 프록시 서버를 통해 node.js를 실행할 수있는 것처럼 보입니다 .
$ proxychains /path/to/node application.js

개인적 으로 Cygwin / Windows 환경 에 프록시 체인 버전 을 설치할 수 없어 테스트 할 수 없었습니다.

또한 그들은 connect-proxy 사용에 대해 이야기 했지만이 작업을 수행하는 방법에 대한 문서를 찾을 수 없습니다.

요컨대, 나는 여전히 붙어 있지만 누군가 가이 정보를 사용하여 적절한 해결 방법을 찾을 수 있습니다.


업데이트 : 일부 조사 결과 RTLD_NEXT가 지원되지 않기 때문에 CygWin에서 프록시 체인을 만들 수 없다는 것을 알게되었습니다.
ddallala


0

이처럼 'https-proxy-agent'를 사용하십시오.

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)=>{...});

0

당신이있는 경우 기본 HTTP 인증 방식을 당신의 base64로 문자열을해야 myuser:mypassword하고 처음에 "기본"을 추가합니다. 이것이 Proxy-Authorization 헤더 의 가치입니다 .

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();

nodejs에서 버퍼 를 사용 하여 인코딩 할 수 있습니다

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

console.log(encodedData);

예를 들어, 브라우저에서 btoa ()를 사용하여 base64로 인코딩 할 수 있으며 프록시 설정을 사용하여 프록시를 사용하여 요청을 수행하지 않고 브라우저의 ajax 요청에 유용합니다.

var encodedData = btoa('myuser:mypassword')

console.log(encodedData);

프록시 구성표를 찾는 방법은 무엇입니까?

사용자 지정 DNS를 구성하지 않은 경우 (ERR_NAME_NOT_RESOLVED와 같은 것을 던질 것), 요청을 수행 할 때 응답 (코드 407)은 프록시가 사용중인 http 인증 체계를 응답 헤더에 알려야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.