109

I am using IBM Bluemix to make a web service for a school project.

My project needs to request a JSON from an API, so I can use the data it provides. I use the http get method for a data set, and I am not sure if it is working properly.

When I run my code, I get the message:

Error: Protocol "https:" not supported. Expected "http:"

What is causing it and how can I solve it?

Here is my .js file:

// Hello.
//
// This is JSHint, a tool that helps to detect errors and potential
// problems in your JavaScript code.
//
// To start, simply enter some JavaScript anywhere on this page. Your
// report will appear on the right side.
//
// Additionally, you can toggle specific options in the Configure
// menu.

function main() {
  return 'Hello, World!';
}

main();/*eslint-env node*/

//------------------------------------------------------------------------------
// node.js starter application for Bluemix
//------------------------------------------------------------------------------

// HTTP request - duas alternativas
var http = require('http');
var request = require('request');

// cfenv provides access to your Cloud Foundry environment
// for more info, see: https://www.npmjs.com/package/cfenv
var cfenv = require('cfenv');

//chama o express, que abre o servidor
var express = require('express');

// create a new express server 
var app = express();

// serve the files out of ./public as our main files
app.use(express.static(__dirname + '/public'));

// get the app environment from Cloud Foundry
var appEnv = cfenv.getAppEnv();

// start server on the specified port and binding host
app.listen(appEnv.port, '0.0.0.0', function() {
    // print a message when the server starts listening
    console.log("server starting on " + appEnv.url);
});


app.get('/home1', function (req,res) {
    http.get('http://developers.agenciaideias.com.br/cotacoes/json', function (res2) {
        var body = '';
        res2.on('data', function (chunk) {
            body += chunk;
        });
        res2.on('end', function () {
            var json = JSON.parse(body);
            var CotacaoDolar = json["dolar"]["cotacao"];
            var VariacaoDolar = json["dolar"]["variacao"];
            var CotacaoEuro = json["euro"]["cotacao"];
            var VariacaoEuro = json["euro"]["variacao"];
            var Atualizacao = json["atualizacao"];

            obj=req.query; 

            DolarUsuario=obj['dolar'];
            RealUsuario=Number(obj['dolar'])*CotacaoDolar;

            EuroUsuario=obj['euro'];
            RealUsuario2=Number(obj['euro'])*CotacaoEuro;

            Oi=1*VariacaoDolar;
            Oi2=1*VariacaoEuro;

            if (VariacaoDolar<0) {
            recomend= "Recomenda-se, portanto, comprar dólares.";
            }

            else if (VariacaoDolar=0){
                recomend="";
            }

            else {
                recomend="Recomenda-se, portanto, vender dólares.";
                  }

            if (VariacaoEuro<0) {
            recomend2= "Recomenda-se, portanto, comprar euros.";
            }

            else if (VariacaoEuro=0){
                recomend2="";
            }
            else {
                recomend2="Recomenda-se,portanto, vender euros.";
                  }   

            res.render('cotacao_response.jade', {
                         'CotacaoDolar':CotacaoDolar,
                        'VariacaoDolar':VariacaoDolar,
                        'Atualizacao':Atualizacao,
                        'RealUsuario':RealUsuario,
                        'DolarUsuario':DolarUsuario,
                        'CotacaoEuro':CotacaoEuro,
                        'VariacaoEuro':VariacaoEuro,
                        'RealUsuario2':RealUsuario2,
                        'recomend':recomend,
                        'recomend2':recomend2,
                        'Oi':Oi,
                        'Oi2':Oi2
            });

        app.get('/home2', function (req,res) {
    http.get('https://www.quandl.com/api/v3/datasets/BCB/432.json?api_key=d1HxqKq2esLRKDmZSHR2', function (res3) {
        var body = '';
        res3.on('data', function (chunk) {
            body += chunk;
        });
        res3.on('end', function () {
            var x=json.dataset.data[0][1];
      console.log("My JSON is "+x); });

    });
    });
        });
    });
});

Here is a print of the error screen I get: enter image description here

Ivan Beldad
  • 2,285
  • 2
  • 21
  • 33
MBBertolucci
  • 1,261
  • 3
  • 13
  • 18

5 Answers5

183

When you want to request an https resource, you need to use https.get, not http.get.

https://nodejs.org/api/https.html

epascarello
  • 204,599
  • 20
  • 195
  • 236
  • 131
    Why is this decision pushed off to the user? It seems like it would be reasonable to just parse the protocol, and use an appropriate function behind the scenes. – Peter Klipfel May 17 '16 at 03:19
  • 8
    Uh, okay? I don't get why this is to be decided by the user. – BastiBen Feb 02 '17 at 14:55
  • 13
    This is maddening. How do I get the last two hours of my life back? – pdoherty926 Mar 30 '20 at 23:01
  • Drives me crazy... I really didn't noticed this thank you... – Sean Reyes Jul 19 '22 at 01:23
  • uh.. what is up with the built-in http module in nodejs? This and the absence of redirect following makes it a PITA to use (and a PITA to use projects which is built on top of it... I've spend 30min now debugging patching a 1.5y old project which would've worked just fine if the http module would've implemented redirects.. (the service used now redirect http to https) – olejorgenb Aug 21 '22 at 12:13
  • in which file this change needs to be done ? I am doing npm install in an empty directory and still getting this error – Anand Kadhi Jan 27 '23 at 14:09
  • npm install of what? – epascarello Jan 27 '23 at 14:13
48

As a side note to anyone looking for a solution from Google... make sure you are not using an http.Agent with an https request or you will get this error.

Eduardo Cuomo
  • 17,828
  • 6
  • 117
  • 94
user169771
  • 1,962
  • 2
  • 13
  • 11
35

The reason for this error is that you are trying to call a HTTPS URI from a HTTP client. The ideal solution would have been for a generic module to figure out the URI protocol and take the decision to use HTTPS or HTTP internally.

The way I overcame this problem is by using the switching logic on my own. Below is some code which did the switching for me.

    var http = require('http');
    var https = require('https');
    // Setting http to be the default client to retrieve the URI.
    var url = new URL("https://www.google.com")
    var client = http; /* default  client */
    // You can use url.protocol as well 
    /*if (url.toString().indexOf("https") === 0){
                client = https;
    }*/
    /* Enhancement : using the  URL.protocol  parameter
     * the  URL  object ,  provides a  parameter url.protocol that gives you 
     * the protocol  value  ( determined  by the  protocol ID  before 
     * the ":" in the  url. 
     * This makes it easier to  determine the protocol, and to  support other  
     * protocols like ftp ,  file  etc) 
     */
   client = (url.protocol == "https:") ? https : client; 
    // Now the client is loaded with the correct Client to retrieve the URI.
    var req = client.get(url, function(res){
        // Do what you wanted to do with the response 'res'.
        console.log(res);
    });
Martin M.
  • 707
  • 7
  • 16
Sarath.B
  • 415
  • 4
  • 6
2

Not sure why, but the issue for me happened after updating node to version 17, i was previously using version 12.

In my setup, i have node-fetch using HttpsProxyAgent as an agent in the options object.

options['agent'] = new HttpsProxyAgent(`http://${process.env.AWS_HTTP_PROXY}`)
response = await fetch(url, options)

Switching back to node 12 fixed the problem:

nvm use 12.18.3
Khalifa
  • 107
  • 1
  • 4
  • For this particular case of `https-proxy-agent`, it happens due to https://github.com/TooTallNate/node-https-proxy-agent/pull/130/files I don't understand why the author did not accept the PR, because you can't update agent-base otherwise. And the fix is explicit in agent-base. I was able to get around it, via yarn resolutions: I force agent-base@6.0.2 instead of 6.0.0 – Alin Galatan Apr 23 '22 at 07:57
0

I got this error while deploying the code.

INFO    error=> TypeError [ERR_INVALID_PROTOCOL]: Protocol "https:" not supported. Expected "http:"
at new NodeError (node:internal/errors:372:5)

To fix this issue, I have updated the "https-proxy-agent" package version to "^5.0.0"

Now the error was gone and it's working for me.