117

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

5 Answers 5

200

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

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

Sign up to request clarification or add additional context in comments.

7 Comments

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.
Uh, okay? I don't get why this is to be decided by the user.
This is maddening. How do I get the last two hours of my life back?
Drives me crazy... I really didn't noticed this 😅 thank you...
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)
|
55

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.

1 Comment

exactly, or even the opposite, using an https agent into an http request.
39

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);
    });

2 Comments

It should be client = (url.protocol == "https:") ? https : client
"https:" with a colon!
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

1 Comment

For this particular case of https-proxy-agent, it happens due to 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 [email protected] instead of 6.0.0
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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.