38

I am trying to use axios with a proxy server to make an https call:

const url = "https://walmart.com/ip/50676589"
var config = { proxy: { host: proxy.ip, port: proxy.port } }

axios.get(url, config)
.then(result => {})
.catch(error => {console.log(error)})

The proxy servers I am using are all in the United States, highly anonymous, with support for HTTP and HTTPS.

I am receiving this error:

{ Error: write EPROTO 140736580649920:error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol:../deps/openssl/openssl/ssl/s23_clnt.c:794:

In order to ensure that the problem is with axios and NOT the proxy, I tried this:

curl -x 52.8.172.72:4444 -L 'https://www.walmart.com/ip/50676589'

This totally works just fine.

How do I configure axios to work with proxies and https URL's?

alayor
  • 4,537
  • 6
  • 27
  • 47
etayluz
  • 15,920
  • 23
  • 106
  • 151

8 Answers8

41

Axios https proxy support is borked if using https proxies. Try passing the proxy through httpsProxyAgent using http.

const axios = require('axios'); 
const httpsProxyAgent = require('https-proxy-agent');

const httpsAgent = new httpsProxyAgent('http://username:pass@myproxy:port');
// or const httpsAgent = new httpsProxyAgent({ host: 'myproxy', port: 9999 });

const config = {
  url: 'https://google.com',
  httpsAgent
}

axios.request(config).then((res) => console.log(res)).catch(err => console.log(err))

Alternatively there is a fork of Axios that incorporates this: axios-https-proxy-fix but I'd recommend the first method to ensure latest Axios changes.

cyberwombat
  • 38,105
  • 35
  • 175
  • 251
  • url should be outside of config, or you will get error "The url argument must be of type string". – cyberspace May 29 '20 at 17:03
  • 1
    @cyberspace what are you talking about? the request method wants a config object. Did you try this with get/post? because those do indeed need the url separate. Docs: https://github.com/axios/axios#request-method-aliases – cyberwombat May 30 '20 at 03:31
  • 7
    in my case had to add also proxy: false in the config – Chris Apr 16 '21 at 09:01
  • @Chris, yes, this is the point that it took me a while to get. We fix the issue with axios's proxy handling by not letting it do proxies at all, doing it all in the https agent (hpagent n my case) instead. – The Archetypal Paul Oct 01 '22 at 16:50
10

Try this. That work for me.

First

npm install axios-https-proxy-fix

Then

import axios from 'axios-https-proxy-fix'; 

const proxy = {
  host: 'some_ip',
  port: some_port_number,
  auth: {
    username: 'some_login',
    password: 'some_pass'
  }
};

async someMethod() {
  const result = await axios.get('some_https_link', {proxy});
}
Ahmed Ashour
  • 5,179
  • 10
  • 35
  • 56
Denis Grushak
  • 185
  • 1
  • 7
8

You can solve this problem looking this issue

At this solution instead use the proxy interface, use the http(s)Agent. For it the solution use the native node module https-proxy-agent.

var ProxyAgent = require('https-proxy-agent');
var axios = require('axios');

const agent = ProxyAgent('http://username:pass@myproxy:port')

var config = {
  url: 'https://google.com',
  proxy: false,
  httpsAgent: agent
};

For it works the proxy property must be equal to false.

2

The https-proxy-agent and node-tunnel solutions did work for me, but both of them doesn't support conditional proxying using NO_PROXY.

I found global-agent as the best solution in my case as it modifies the core http and https objects and will be applied automatically to any library that makes use of them, including axios, got, request, etc.

The usage is very simple.

npm i global-agent
npm i -D @types/global-agent

Add import 'global-agent/bootstrap'; to the entrypoint (index.ts) of the server.

Run with these env vars and make sure HTTP_PROXY, HTTPS_PROXY are NOT in the env.

export GLOBAL_AGENT_NO_PROXY='*.foo.com,baz.com'
export GLOBAL_AGENT_HTTP_PROXY=http://127.0.0.1:8080

This is how I finally ended up using it.

import { bootstrap } from 'global-agent';

const proxy = process.env.EXTERNAL_PROXY;

if (proxy) {
  process.env.GLOBAL_AGENT_HTTP_PROXY = proxy;
  process.env.GLOBAL_AGENT_NO_PROXY = process.env.NO_PROXY;
  process.env.GLOBAL_AGENT_FORCE_GLOBAL_AGENT = 'false';
  bootstrap();
  logger.info(`External proxy ${proxy} set`);
}
Sidharth V
  • 181
  • 3
  • 13
2

I know this is an old post, but I hope this solution saves time for anyone facing an SSL issue with Axios.

  • You can use an HTTP agent, I suggest using hpagent
const axios = require("axios");
const { HttpProxyAgent, HttpsProxyAgent } = require("hpagent");

async function testProxy() {
  try {
    const proxy = "http://username:password@myproxy:port";
    // hpagent configuration
    let agentConfig = {
      proxy: proxy,
      // keepAlive: true,
      // keepAliveMsecs: 2000,
      // maxSockets: 256,
      // maxFreeSockets: 256,
    };
    axios.defaults.httpAgent = new HttpProxyAgent(agentConfig);
    axios.defaults.httpsAgent = new HttpsProxyAgent(agentConfig);
    // Make a simple request to check for the IP address.
    let res = await axios.get("https://api.ipify.org/?format=json");
    console.log(res.data);
  } catch (error) {
    console.error(error);
  }
}

testProxy();
1

Try to explicitly specify the port in the URL:

const url = "https://walmart.com:443/ip/50676589"

If you also need an HTTPS-over-HTTP tunnel, you'll find a solution in this article.

Hope this helps,

Jan

Jan Molak
  • 4,426
  • 2
  • 36
  • 32
  • Why a downvote? Axios had (has?) an issue where specifying the port number forced it to use the https agent rather than the http agent. – Jan Molak Apr 04 '19 at 15:11
0

This error is because axios is trying to proxy your request via https (it takes it from your url), there is this ticket tracking it: https://github.com/axios/axios/issues/925

Sergio
  • 491
  • 4
  • 11
0

I lost a day of work when I updated my dependencies last week (Feb. 2020) trying to figure out why services were stalling. axios-https-proxy-fix will cause Axios to hang indefinitely without timeout or throwing an error conflicting with other libraries in npm. Using node-tunnel (https://github.com/koichik/node-tunnel) to create an agent also works.

const tunnel = require('tunnel');
class ApiService {
  get proxyRequest() {
    const agent = tunnel.httpsOverHttp({
      proxy: {
        host: 'http://proxy.example.com',
        port: 22225,
        proxyAuth: `username:password`,
      },
    });
    return axios.create({
      agent,
    })
  }
}
Adam S
  • 509
  • 10
  • 24