Tôi muốn thực hiện một cuộc gọi HTTP gửi đi từ node.js, sử dụng tiêu chuẩn http.Client
. Nhưng tôi không thể truy cập máy chủ từ xa trực tiếp từ mạng của mình và cần thông qua proxy.
Làm cách nào để tôi nói với node.js sử dụng proxy?
Tôi muốn thực hiện một cuộc gọi HTTP gửi đi từ node.js, sử dụng tiêu chuẩn http.Client
. Nhưng tôi không thể truy cập máy chủ từ xa trực tiếp từ mạng của mình và cần thông qua proxy.
Làm cách nào để tôi nói với node.js sử dụng proxy?
Câu trả lời:
Câu trả lời của Tim Macfarlane rất gần với việc sử dụng proxy HTTP.
Sử dụng proxy HTTP (đối với các yêu cầu không bảo mật) rất đơn giản. Bạn kết nối với proxy và thực hiện yêu cầu bình thường ngoại trừ phần đường dẫn bao gồm url đầy đủ và tiêu đề máy chủ được đặt thành máy chủ bạn muốn kết nối.
Tim rất gần với câu trả lời của anh ấy nhưng anh ấy đã bỏ lỡ việc đặt tiêu đề máy chủ đúng cách.
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);
});
Đối với bản ghi, câu trả lời của anh ta không hoạt động với http://nodejs.org/ nhưng đó là do máy chủ của họ không quan tâm đến tiêu đề máy chủ không chính xác.
404
và máy chủ đích không bao giờ nhận được yêu cầu ..
Bạn có thể sử dụng yêu cầu , tôi chỉ thấy nó dễ sử dụng proxy trên node.js, chỉ với một tham số "proxy" bên ngoài, thậm chí nhiều hơn nó còn hỗ trợ HTTPS thông qua proxy http.
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);
}
})
http
và https
trong trường hợp của tôi, Cảm ơn rất nhiều
Một điều khiến tôi mất một thời gian để tìm ra, sử dụng 'http' để truy cập proxy, ngay cả khi bạn đang cố gắng ủy quyền qua máy chủ https. Điều này hoạt động với tôi bằng cách sử dụng Charles (phân tích giao thức 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);
});
Như @Renat ở đây đã được đề cập, lưu lượng HTTP được ủy quyền xuất hiện trong các yêu cầu HTTP khá bình thường. Thực hiện yêu cầu đối với proxy, chuyển URL đầy đủ của đích đến dưới dạng đường dẫn.
var http = require ('http');
http.get ({
host: 'my.proxy.com',
port: 8080,
path: 'http://nodejs.org/'
}, function (response) {
console.log (response);
});
Tôi nghĩ rằng tôi sẽ thêm mô-đun này mà tôi đã tìm thấy: https://www.npmjs.org/package/global-tunnel , hoạt động rất tốt cho tôi (Làm việc ngay lập tức với tất cả các mô-đun mã của tôi và bên thứ ba chỉ với mã bên dưới).
require('global-tunnel').initialize({
host: '10.0.0.10',
port: 8080
});
Thực hiện việc này một lần và tất cả http (và https) trong ứng dụng của bạn đều đi qua proxy.
Thay phiên, gọi
require('global-tunnel').initialize();
Sẽ sử dụng http_proxy
biến môi trường
Tôi đã mua máy chủ proxy riêng, sau khi mua tôi nhận được:
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
Và tôi muốn sử dụng nó. Câu trả lời đầu tiên và câu trả lời thứ hai chỉ hoạt động cho http (proxy) -> http (đích), tuy nhiên tôi muốn http (proxy) -> https (đích).
Và đối với đích https, tốt hơn là sử dụng trực tiếp đường hầm HTTP . Tôi tìm thấy giải pháp ở đây . Mã cuối cùng:
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()
Gói http 'yêu cầu' dường như có tính năng này:
https://github.com/mikeal/request
Ví dụ: đối tượng yêu cầu 'r' bên dưới sử dụng localproxy để truy cập các yêu cầu của nó:
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)
}
})
Thật không may, không có mặc định "toàn cầu" để người dùng lib sử dụng điều này không thể sửa đổi proxy trừ khi lib chuyển qua các tùy chọn http ...
HTH, Chris
Về cơ bản, bạn không cần một hỗ trợ proxy rõ ràng. Giao thức proxy khá đơn giản và dựa trên giao thức HTTP thông thường. Bạn chỉ cần sử dụng máy chủ proxy và cổng khi kết nối với HTTPClient. Ví dụ (từ tài liệu của 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();
...
Vì vậy, về cơ bản, bạn kết nối với proxy của mình nhưng thực hiện một yêu cầu tới "http://www.google.com".
Trong trường hợp bạn cần sử dụng ủy quyền cơ bản cho nhà cung cấp proxy của mình, chỉ cần sử dụng như sau:
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();
Nút nên hỗ trợ sử dụng biến môi trường http_proxy - vì vậy nó là nền tảng chéo và hoạt động trên các cài đặt hệ thống thay vì yêu cầu cấu hình trên mỗi ứng dụng.
Sử dụng các giải pháp được cung cấp, tôi muốn giới thiệu như sau:
Bản thảo
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);
};
Cách sử dụng Để sử dụng phương thức, chỉ cần thay thế http.get một cách hiệu quả, ví dụ như sau đây ghi trang chỉ mục của google vào một tệp có tên 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"
Câu trả lời của Imskull gần như có tác dụng với tôi, nhưng tôi phải thực hiện một số thay đổi. Thay đổi thực sự duy nhất là thêm tên người dùng, mật khẩu và đặt từ chốiUnauthorized thành false. Tôi không thể bình luận vì vậy tôi đưa ra câu trả lời.
Nếu bạn chạy mã, nó sẽ giúp bạn có được tiêu đề của những câu chuyện hiện tại trên Hacker News, theo hướng dẫn này: http://smalljs.org/package-manager/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.');
}
});
Tôi nghĩ rằng có một sự thay thế tốt hơn cho các câu trả lời vào năm 2019. Chúng ta có thể sử dụng global-tunnel-ng
gói để khởi tạo proxy và không gây ô nhiễm http
hoặc https
mã dựa trên mọi nơi. Vì vậy, global-tunnel-ng
gói cài đặt đầu tiên :
npm install global-tunnel-ng
Sau đó thay đổi triển khai của bạn để khởi tạo proxy nếu cần là:
const globalTunnel = require('global-tunnel-ng');
globalTunnel.initialize({
host: 'proxy.host.name.or.ip',
port: 8080
});
Có thể không phải là một lớp lót chính xác mà bạn hy vọng nhưng bạn có thể xem http://github.com/nodejitsu/node-http-proxy vì điều đó có thể làm sáng tỏ cách bạn có thể sử dụng ứng dụng của mình với http. Khách hàng.
Dựa trên câu trả lời từ chủ đề này nó sẽ có vẻ như bạn có thể sử dụng proxychains
để chạy Node.js thông qua máy chủ proxy:
$ proxychains /path/to/node application.js
Cá nhân tôi không thể cài đặt bất kỳ phiên bản proxy nào trên Cygwin / Windows môi trường nên không thể kiểm tra nó.
Hơn nữa, họ cũng nói về việc sử dụng kết nối proxy nhưng tôi không thể tìm thấy bất kỳ tài liệu nào về cách thực hiện việc này.
Nói tóm lại, tôi vẫn bị mắc kẹt, nhưng có lẽ ai đó có thể sử dụng thông tin này để tìm một công việc phù hợp.
Để sử dụng proxy với https, tôi đã thử lời khuyên trên trang web này (sử dụng tác nhân https-proxy phụ thuộc ) và nó hoạt động với tôi:
http://codingmiles.com/node-js-making-https-request-via-proxy/
sử dụng 'https-proxy-agent' như thế này
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)=>{...});
Nếu bạn có sơ đồ xác thực http cơ bản, bạn phải tạo một chuỗi base64 myuser:mypassword
và sau đó thêm "Cơ bản" vào đầu. Đó là giá trị của tiêu đề Ủy quyền Proxy , đây là một ví dụ:
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();
Trong nodejs bạn có thể sử dụng Bộ đệm để mã hóa
var encodedData = Buffer.from('myuser:mypassword').toString('base64');
console.log(encodedData);
Ví dụ, trong các trình duyệt, bạn có thể mã hóa trong base64 bằng btoa () , hữu ích trong các yêu cầu ajax trong trình duyệt mà không cần cài đặt proxy thực hiện yêu cầu bằng proxy.
var encodedData = btoa('myuser:mypassword')
console.log(encodedData);
Làm thế nào để tìm chương trình wich chấp nhận máy chủ proxy?
Nếu chúng tôi không có DNS tùy chỉnh được định cấu hình (sẽ ném một cái gì đó như ERR_NAME_NOT_RESOLVED), khi chúng tôi thực hiện một yêu cầu, phản hồi (mã 407) sẽ thông báo trong tiêu đề phản hồi mà chương trình xác thực http mà proxy đang sử dụng.