2010-10-05 55 views
106

我想使用標準http.Client從node.js發出傳出的HTTP呼叫。但是我無法直接從我的網絡到達遠程服務器,需要通過代理。如何在node.js http.Client中使用http代理?

如何告訴node.js使用代理?

+0

我遇到同樣的問題。 Node.js位於防火牆之後,我無法創建HTTPClient到外部網站。 – ddallala 2010-12-28 17:11:33

回答

121

Tim Macfarlaneanswer接近至於使用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/工作,但那是因爲他們的服務器不關心主機頭不正確。

+0

有沒有辦法使用http代理連接https端口?似乎沒有簡單的方法 – Gohan 2011-12-30 09:38:31

+0

@Gohan關於如何通過http代理連接到https服務器的示例,請參閱Chris的答案。 – HairOfTheDog 2012-07-19 03:36:13

+0

如果您收到錯誤的請求,請將路徑:'/' – 2013-06-01 12:03:38

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 2011-06-15 09:15:16

+1

從v5.6開始,它顯然不再適用於node.js,因爲它們已經刪除了[createClient](http://nodejs.org/docs /v0.5.6/api/http.html#http.ClientResponse)。 – Marc 2011-09-10 15:18:07

0

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

基於從這個線程的答案它會像你可以使用proxychains 通過代理服務器的nod​​e.js運行:
$ proxychains /path/to/node application.js

個人我不是無法安裝任何的代理鏈版本Cygwin/Windows環境因此無法測試它。

此外,他們還談到了使用連接代理,但我找不到任何有關如何執行此操作的文檔。

總之,我仍然卡住了,但也許有人可以使用此信息來找到合適的解決辦法。

+0

更新:經過一些調查發現,我不能在CygWin上構建代理鏈,因爲RTLD_NEXT不受支持。 – ddallala 2010-12-29 16:29:45

14

作爲@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); 
}); 
+1

雖然Fiddler把它稱爲協議違規,這表明它不是一個正確的HTTP請求 - 通過代理,這似乎工作... – Marc 2011-09-10 15:09:34

27

有一兩件事,我花了一段時間才能弄清楚,使用「HTTP」訪問代理,即使你通過一個HTTPS服務器試圖代理。這工作我用查爾斯(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); 
}); 
+3

+1你救了我! HTTP到HTTPS請求的代理。 – aggsol 2013-07-11 11:55:06

+0

你也救了我。謝謝。 – c4il 2014-01-24 00:36:03

+1

上面的代碼不適用於我,它與https://github.com/joyent/node/issues/2474有關https://github.com/joyent/node/issues/2474檢查koichik的答案,我們必須使用「方法」:「連接」和「連接」事件,我們發送路徑信息。 – Palani 2014-08-28 18:53:17

8

的 '請求' 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通過http選項...

HTH,Chris

+0

請求HTTP包讓您的代碼更容易切換代理和非代理使用情況(這是我的筆記本電腦相當有用)之間切換。 – 2015-04-28 23:20:41

3

節點應該支持使用http_proxy環境變量 - 所以它是跨平臺的並且在系統設置上工作而不是要求每個應用程序配置。

使用所提供的解決方案,我想提出以下建議:

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

使用 要使用其實現方法具d,有效只需更換http.get,例如下面谷歌的索引頁寫入一個文件名爲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" 
+0

在Windows上運行Node時,設置http_proxy似乎沒有任何效果。 – EricLaw 2014-01-06 20:01:34

+0

它應該在Windows下工作(這是我使用的主要系統)。確保設置好後,重置終端會話(如果通過控制面板進行設置而未設置)。您應該能夠使用 echo%HTTP_PROXY% 或更好,您應該使用節點本身 node -e「console.log(process.env.http_proxy);」 這對我在Windows下工作,所以祝你好運。 – Luke 2014-01-06 22:14:12

42

您可以使用request,我才發現這是令人難以置信的容易節點使用代理.js,只需一個外部「代理」參數,甚至可以通過http代理支持HTTPS。

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

在我的情況下,爲'http'和'https'工作,非常感謝 – blumonkey 2015-06-29 13:38:14

+0

爲什麼這不適用於內部公司頁面的任何想法? – keinabel 2015-07-03 11:41:32

+1

我很驚訝內部的公司頁面是在代理的背後。你確定代理沒有被內部頁面繞過嗎?它在不同的vlan上? – Chanoch 2015-08-11 08:24:19

8

思想我想補充一點模塊,我發現: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 2015-02-08 19:36:45

+0

完美,效果很好,謝謝 – 2015-03-02 09:51:18

+0

它是否適用於https流量? – 2017-05-08 13:47:04

3

在您需要爲您的代理提供商使用基本授權的情況下,只需使用以下命令:

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

我在哪裏可以找到「FarmerAdapter」? – Alex 2016-07-18 12:31:16

1

艾姆斯卡爾的答案几乎適用於我,但我不得不做出一些改變。唯一真正的變化是添加用戶名,密碼,並將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:[email protected]: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.'); 
    } 
}); 
0

使用「HTTPS代理 - 代理」類似這樣的

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