Voglio effettuare una chiamata HTTP in uscita da node.js, usando lo standard http.Client
. Ma non riesco a raggiungere il server remoto direttamente dalla mia rete e devo passare attraverso un proxy.
Come posso dire a node.js di usare il proxy?
Voglio effettuare una chiamata HTTP in uscita da node.js, usando lo standard http.Client
. Ma non riesco a raggiungere il server remoto direttamente dalla mia rete e devo passare attraverso un proxy.
Come posso dire a node.js di usare il proxy?
Risposte:
La risposta di Tim Macfarlane era vicina per quanto riguarda l'uso di un proxy HTTP.
L'uso di un proxy HTTP (per richieste non sicure) è molto semplice. Ti connetti al proxy ed esegui normalmente la richiesta, tranne per il fatto che la parte del percorso include l'URL completo e l'intestazione dell'host è impostata sull'host a cui desideri connetterti.
Tim è stato molto vicino con la sua risposta ma ha perso l'impostazione corretta dell'intestazione host.
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);
});
Per la cronaca, la sua risposta funziona con http://nodejs.org/, ma è perché il loro server non si preoccupa che l'intestazione dell'host sia errata.
404
e il server di destinazione non riceve mai la richiesta.
Puoi usare la richiesta , ho appena scoperto che è incredibilmente facile usare il proxy su node.js, solo con un parametro "proxy" esterno, ancora di più supporta HTTPS attraverso un 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
e https
nel mio caso, grazie mille
Una cosa che mi ci è voluto un po 'di tempo per capire, usa' http 'per accedere al proxy, anche se stai provando a fare il proxy su un server HTTPS. Questo funziona per me usando Charles (analizzatore di protocollo 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);
});
Come già accennato da @Renat, il traffico HTTP con proxy arriva in richieste HTTP piuttosto normali. Invia la richiesta al proxy, passando l' URL completo della destinazione come percorso.
var http = require ('http');
http.get ({
host: 'my.proxy.com',
port: 8080,
path: 'http://nodejs.org/'
}, function (response) {
console.log (response);
});
Ho pensato di aggiungere questo modulo che ho trovato: https://www.npmjs.org/package/global-tunnel , che ha funzionato benissimo per me (ha funzionato immediatamente con tutto il mio codice e moduli di terze parti con solo il codice seguente).
require('global-tunnel').initialize({
host: '10.0.0.10',
port: 8080
});
Fallo una volta, e tutti gli http (e https) nella tua applicazione passano attraverso il proxy.
In alternativa, chiamando
require('global-tunnel').initialize();
Userà la http_proxy
variabile d'ambiente
Ho acquistato un server proxy privato, dopo l'acquisto ho ottenuto:
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
E volevo usarlo. La prima e la seconda risposta hanno funzionato solo per http (proxy) -> http (destinazione), tuttavia volevo http (proxy) -> https (destinazione).
E per la destinazione https sarebbe meglio usare il tunnel HTTP direttamente. Ho trovato una soluzione qui . Codice finale:
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()
Il pacchetto http 'request' sembra avere questa funzione:
https://github.com/mikeal/request
Ad esempio, l'oggetto richiesta 'r' di seguito utilizza localproxy per accedere alle sue richieste:
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)
}
})
Sfortunatamente non ci sono impostazioni predefinite "globali" in modo che gli utenti di librerie che lo utilizzano non possano modificare il proxy a meno che la libreria non passi attraverso le opzioni http ...
HTH, Chris
Fondamentalmente non è necessario un supporto proxy esplicito. Il protocollo proxy è piuttosto semplice e basato sul normale protocollo HTTP. Devi solo usare il tuo host proxy e la tua porta quando ti connetti a HTTPClient. Esempio (dai documenti 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();
...
Quindi sostanzialmente ti connetti al tuo proxy ma fai una richiesta a "http://www.google.com".
Nel caso in cui sia necessario utilizzare l'autorizzazione di base per il proprio provider proxy, utilizzare semplicemente quanto segue:
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();
Il nodo dovrebbe supportare l'utilizzo della variabile ambientale http_proxy, quindi è multipiattaforma e funziona sulle impostazioni di sistema piuttosto che richiedere una configurazione per applicazione.
Utilizzando le soluzioni fornite, consiglierei quanto segue:
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);
};
Utilizzo Per utilizzare il metodo, sostituire semplicemente http.get, ad esempio quanto segue scrive la pagina dell'indice di google in un file chiamato 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"
La risposta di Imskull ha quasi funzionato per me, ma ho dovuto apportare alcune modifiche. L'unica vera modifica è l'aggiunta di nome utente, password e impostazione rifiuta non autorizzata su falso. Non ho potuto commentare, quindi ho inserito una risposta.
Se esegui il codice otterrai i titoli delle storie attuali su Hacker News, per questo 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.');
}
});
Penso che ci sia un'alternativa migliore alle risposte a partire dal 2019. Possiamo usare il global-tunnel-ng
pacchetto per inizializzare il proxy e non inquinare il codice http
o https
basato ovunque. Quindi primo global-tunnel-ng
pacchetto di installazione :
npm install global-tunnel-ng
Quindi modificare le implementazioni per inizializzare il proxy se necessario come:
const globalTunnel = require('global-tunnel-ng');
globalTunnel.initialize({
host: 'proxy.host.name.or.ip',
port: 8080
});
Potrebbe non essere l'esatto one-liner che speravi, ma potresti dare un'occhiata a http://github.com/nodejitsu/node-http-proxy in quanto ciò potrebbe far luce su come puoi usare la tua app con http. Cliente.
Sulla base delle risposte di questo thread sembrerebbe che potresti usare proxychains
per eseguire node.js attraverso il server proxy:
$ proxychains /path/to/node application.js
Personalmente non sono stato in grado di installare nessuna delle versioni di proxychains su Cygwin / Windows ambiente , quindi non ho potuto testarlo.
Inoltre, hanno anche parlato dell'utilizzo di connect-proxy ma non sono riuscito a trovare alcuna documentazione su come eseguire questa operazione.
In breve, sono ancora bloccato, ma forse qualcuno può usare queste informazioni per trovare una soluzione adeguata.
Per usare un proxy con https ho provato i consigli su questo sito (usando la dipendenza https-proxy-agent ) e ha funzionato per me:
http://codingmiles.com/node-js-making-https-request-via-proxy/
Se si dispone dello schema di autenticazione http di base , è necessario creare una stringa base64 myuser:mypassword
, quindi aggiungere "Base" all'inizio. Questo è il valore dell'intestazione Proxy-Authorization , qui un esempio:
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();
In nodejs è possibile utilizzare Buffer per codificare
var encodedData = Buffer.from('myuser:mypassword').toString('base64');
console.log(encodedData);
Proprio come ad esempio, nei browser è possibile codificare in base64 usando btoa () , utile nelle richieste ajax in un browser senza impostazioni proxy che eseguono una richiesta tramite proxy.
var encodedData = btoa('myuser:mypassword')
console.log(encodedData);
Come trovare quale schema accetta il server proxy?
Se non abbiamo configurato un DNS personalizzato (che genererebbe qualcosa come ERR_NAME_NOT_RESOLVED), quando eseguiamo una richiesta, la risposta (codice 407) dovrebbe indicare nelle intestazioni di risposta quale schema di autenticazione http sta utilizzando il proxy.