#node.js #http #https #proxy #http-proxy
#node.js #http #https #прокси #http-прокси
Вопрос:
Я пытаюсь отправить http (запросы GET и POST) на различные сайты для получения информации о заголовке / теле ответа, и мне нужно изменить, использую ли я прокси или нет. После того, как ранее не удалось использовать библиотеку restler для этой цели, я переключился на библиотеки узлов http и https для выполнения этих задач. Код следующим образом:
/******/
//Http client libraries
var http = require("http");
var https = require("https");
//Request URL
var url = 'http://whatismyip.akamai.com';
//var url = 'https://en.wikipedia.org/wiki/Main_Page';
//Proxy config
var USE_PROXY = false;
var PROXY_PROTOCOL= 'http';
var PROXY_HOST= '127.0.0.1';
var PROXY_PORT= 6401;
/******/
//Define request options
var protocol = (USE_PROXY ? (PROXY_PROTOCOL == 'https' ? https : http) : (getProtocolFromUrl(url) == 'https' ? https : http));
var host = (USE_PROXY ? PROXY_HOST : getDomainFromUrl(url));
var port = (USE_PROXY ? PROXY_PORT : (getProtocolFromUrl(url) == 'https' ? 443 : 80));
var path = (USE_PROXY ? url : getPathFromUrl(url));
console.log('options.host = ' host);
console.log('options.port = ' port);
console.log('options.path = ' path);
console.log('n');
//Make the request
protocol.get({host: host, port: port, path: path}, function(res) {
console.log('x-client-ip header: ' res.headers['x-client-ip']);
console.log('Status code: ' res.statusCode);
if ([301,302,303].indexOf(res.statusCode) > -1){
console.log('location header : ' res.headers["location"]);
console.log('Redirect url: ' combineUrls(res.headers["location"],url));
} else {
res.on('data', function (data) {
console.log('Response body: ' data.toString());
});
}
}).on('error', function(err) {
console.log(err);
});
В приведенном выше примере хост / порт / путь, указанные в параметрах запроса, определяются из URL-адреса и набора конфигурации прокси-сервера (как и использование библиотеки http или https). Чтобы проверить, что используются правильные настройки прокси-сервера, я проверяю IP-адрес запроса, считываемый хост-сервером, следующим образом:
- протокол http: тело ответа от http://whatismyip.akamai.com /
- протокол https: заголовок x-client-ip из https://en.wikipedia.org/wiki/Main_Page
При отсутствии установленного прокси-сервера это результаты:
1.
options.host = whatismyip.akamai.com
options.port = 80
options.path = /
x-client-ip header: undefined
Status code: 200
Response body: **.**.**.** (public IP)
options.host = en.wikipedia.org
options.port = 443
options.path = /wiki/Main_Page
x-client-ip header: **.**.**.** (public IP)
Status code: 200
Response body: <!DOCTYPE html> //etc...
Однако, если я попытаюсь использовать прокси-сервер (который маршрутизирует запросы через привязанное мобильное устройство и использует его мобильную сеть), я получаю следующие результаты:
1.
options.host = 127.0.0.1
options.port = 6401
options.path = http://whatismyip.akamai.com
x-client-ip header: undefined
Status code: 400
Response body: <HTML><HEAD>
<TITLE>Invalid URL</TITLE>
</HEAD><BODY>
<H1>Invalid URL</H1>
The requested URL "httpamp;#58;amp;#47;whatismyipamp;#46;akamaiamp;#46;com", is invalid.<p>
Referenceamp;#32;amp;#35;9amp;#46;64fcff5aamp;#46;1605358006amp;#46;0
</BODY></HTML>
options.host = 127.0.0.1
options.port = 6401
options.path = https://en.wikipedia.org/wiki/Main_Page
x-client-ip header: **.**.**.** (Proxy IP)
Status code: 301
location header : https://en.wikipedia.org/wiki/Main_Page
Redirect url: https://en.wikipedia.org/wiki/Main_Page
Таким образом, при использовании настроек прокси-сервера, похоже, возникают 2 проблемы — в первом запросе код ответа равен http400, а в теле указано, что указанный путь зашифрован. Странно то, что иногда я могу заставить его работать, если я перепишу код и жестко закодирую настройки, например:
http.get({
host: '127.0.0.1',
port: 6401,
path: 'http://whatismyip.akamai.com/'
}, function (res) {
console.log('Status code: ' res.statusCode);
res.on('data', function (data) {
console.log('Response body: ' data.toString());
});
});
вернет:
Status code: 200
Response body: **.**.**.** (Proxy IP)
Поэтому в настоящее время я не могу объяснить, почему в предыдущем коде произошел сбой.
Во втором случае с протоколом https возвращается код ответа 301, но местоположение перенаправления совпадает с исходным URL-адресом, поэтому должна быть проблема со способом представления пути при пересылке запроса на хост-сервер.
*** Редактировать ***
Как и предлагалось, попробовал использовать другие библиотеки запросов. Пример с axios ниже:
axios.get('https://en.wikipedia.org/wiki/Main_Page',{
proxy: {
host: '127.0.0.1',
port: 6401
}
}).then(function (res) {
console.log(res.status);
console.log(res.headers['x-client-ip']);
//console.log(res.data);
}).catch(function (err) {
console.log(err);
});
В этом случае вместо IP-адреса прокси-сервера был возвращен общедоступный IP-адрес.
Комментарии:
1. Почему вы не используете что-то вроде
axios
илиgot
для выполнения запросов? Они оба поддерживают прокси2. Нет причин, по которым я не могу переключиться, если я могу заставить любой из них работать. Я пробовал использовать axios, но он по-прежнему возвращает общедоступный IP-адрес вместо IP-адреса прокси-сервера — см. Редактирование исходного вопроса для кода.