¿Cómo puedo usar un proxy http con node.js http.Client?
(16)
Quiero hacer una llamada HTTP saliente desde node.js, usando el http.Client
estándar. Pero no puedo acceder al servidor remoto directamente desde mi red y necesito pasar por un proxy.
¿Cómo le digo a node.js que use el proxy?
Aquí solo una muestra simple si no quiere usar crypto o Buffer. Puede hacer una codificación base64 de -> myuser: mypassword, y luego agregar "Basic" al principio. Ese es el valor del encabezado "Proxy-Authorization".
var Http = require(''http'');
var req = Http.request({
host: ''myproxy.com.zx'',
port: 8080,
headers:{"Proxy-Authorization": "Basic bXl1c2VyOm15cGFzcw"},
method: ''GET'',
path: ''http://www.google.com/''
}, function (res) {
res.on(''data'', function (data) {
console.log(data.toString());
});
});
req.end();
Básicamente, no necesita un soporte de proxy explícito. El protocolo proxy es bastante simple y se basa en el protocolo HTTP normal. Solo necesita usar su host y puerto proxy cuando se conecta con HTTPClient. Ejemplo (desde node.js docs):
var http = require(''http'');
var google = http.createClient(3128, ''your.proxy.host'');
var request = google.request(''GET'', ''/'',
{''host'': ''www.google.com''});
request.end();
...
Así que, básicamente, te conectas a tu proxy pero haces una solicitud a "http://www.google.com".
Como @Renat aquí ya se mencionó, el tráfico HTTP con proxy viene en solicitudes HTTP bastante normales. Realice la solicitud en contra del proxy, pasando la URL completa del destino como la ruta.
var http = require (''http'');
http.get ({
host: ''my.proxy.com'',
port: 8080,
path: ''http://nodejs.org/''
}, function (response) {
console.log (response);
});
Compré un servidor proxy privado, después de la compra obtuve:
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
Y yo quería usarlo La primera respuesta y la segunda respuesta funcionaron solo para http (proxy) -> http (destino), sin embargo, quería http (proxy) -> https (destino).
Y para el destino https, sería mejor usar el túnel HTTP directamente. Encontré una solución here . Código final:
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()
El paquete http ''de solicitud'' parece tener esta característica:
Por ejemplo, el objeto de solicitud ''r'' a continuación usa localproxy para acceder a sus solicitudes:
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)
}
})
Lamentablemente, no hay valores predeterminados "globales", por lo que los usuarios de libs que usan esto no pueden modificar el proxy a menos que la lib pase a través de las opciones http ...
HTH, Chris
En caso de que necesite utilizar la autorización básica para su proveedor de proxy, solo use lo siguiente:
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();
La answer Tim Macfarlane estuvo cerca de usar un proxy HTTP.
Usar un proxy HTTP (para solicitudes no seguras) es muy simple. Se conecta al proxy y realiza la solicitud normalmente, excepto que la parte de la ruta incluye la url completa y el encabezado del host se establece en el host al que desea conectarse.
Tim estuvo muy cerca con su respuesta, pero olvidó configurar el encabezado de host correctamente.
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);
});
Para que conste, su respuesta funciona con http://nodejs.org/ pero eso se debe a que a su servidor no le importa que el encabezado del host sea incorrecto.
La respuesta de Imskull casi funcionó para mí, pero tuve que hacer algunos cambios. El único cambio real es agregar nombre de usuario, contraseña y configuración de rechazo no autorizado a falso. No pude comentar, así que puse esto en una respuesta.
Si ejecuta el código, obtendrá los títulos de las historias actuales en Hacker News, según este 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.'');
}
});
Node debería admitir el uso de la variable de entorno http_proxy, por lo que es multiplataforma y funciona en la configuración del sistema en lugar de requerir una configuración por aplicación.
Usando las soluciones proporcionadas, recomendaría lo siguiente:
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);
};
Uso Para usar el método, simplemente reemplace http.get, por ejemplo, lo siguiente escribe la página de índice de google en un archivo llamado 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"
Para usar un proxy con https intenté el consejo en este sitio web (usando la dependencia https-proxy-agent ) y funcionó para mí:
http://codingmiles.com/node-js-making-https-request-via-proxy/
Pensé que agregaría este módulo que encontré: https://www.npmjs.org/package/global-tunnel , que funcionó muy bien para mí (Trabajé inmediatamente con todo mi código y módulos de terceros con solo el siguiente código).
require(''global-tunnel'').initialize({
host: ''10.0.0.10'',
port: 8080
});
Haga esto una vez, y todos los http (y https) en su aplicación pasan por el proxy.
Alternativamente, llamando
require(''global-tunnel'').initialize();
Utilizará la variable de entorno http_proxy
Puede que no sea la línea exacta que esperabas, pero puedes echarle un vistazo a http://github.com/nodejitsu/node-http-proxy ya que puede arrojar algo de luz sobre cómo puedes usar tu aplicación con http. Cliente.
Puede usar la request . Acabo de encontrar que es increíblemente fácil de usar proxy en node.js, solo con un parámetro externo de "proxy", y más aún es compatible con HTTPS a través de un proxy HTTP.
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);
}
})
Una cosa que me tomó un tiempo descifrar, use ''http'' para acceder al proxy, incluso si está tratando de realizar un proxy a través de un servidor https. Esto funciona para mí usando Charles (analizador de protocolo 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);
});
use ''https-proxy-agent'' como este
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)=>{...});
En función de las respuestas de este hilo, parece que podría usar proxychains de caracteres proxy para ejecutar node.js a través del servidor proxy:
$ proxychains /path/to/node application.js
Personalmente, no pude instalar ninguna de las versiones de proxychains en el entorno de Cygwin / Windows , así que no pude probarlo.
Además, también hablaron sobre el uso de connect-proxy, pero no pude encontrar ninguna documentación sobre cómo hacer esto.
En resumen, todavía estoy atascado, pero tal vez alguien pueda usar esta información para encontrar una solución adecuada.