Search code examples
jqueryxmlhttprequest

My JQuery ipify API call Using XMLHttpRequest is returning a Status 405 Error


This is the code for my http://api.ipify.org call:

    function getInfo(website)
    {

      var xhr = new XMLHttpRequest();
      //change this string to the lambda_insertPromoter string.
      // fuckCORS + 
      var url = website;
      console.log("getInfo");
      //alert(data);        
      xhr.open("POST", url, true);
      xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
      xhr.setRequestHeader("Accept","application/json");
      xhr.setRequestHeader("X-Requested-With","XMLHttpRequest");

      xhr.onreadystatechange = function () {
          if (this.readyState == 4 && this.status == 200) {

            var json = JSON.parse(xhr.responseText);
            console.log(json);
            var ip_address = json.ip;
            console.log(ip_address)
            return ip_address;

          }
          else if (this.readyState == 4 && this.status >= 400 && this.status < 500)
          {
            console.log(this);
            console.log("getInfo: readyState == 4 && status >= 400 && status < 500");
          }
          else if (this.readyState == 4 && this.status >= 500)
          {
            console.log("getInfo: readyState == 4 && status >= 500");
          }
        }

      xhr.send();

    }

    var ip_address_2 = getInfo("https://cors-anywhere.herokuapp.com/https://api.ipify.org/?format=json&callback=?");

    alert(ip_address_2);

When I run this request I get this response:

XMLHttpRequest { onreadystatechange: onreadystatechange(), readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, responseURL: "https://cors-anywhere.herokuapp.com/https://api.ipify.org/?format=json&callback=?", status: 405, statusText: "Method Not Allowed", responseType: "", response: "" }

The response I'm getting is a status 405 code which means that the site is getting the request but it's not working.

What changes should I make to get the IP address I need?


Solution

  • What HTTP 405 actually means is method not allowed which means the url you're trying to reach via POST does not allow POST. Use GET. Also, the way you're trying to get the return values: var ip_address_2 = ... will not work because you're making an HTTP request, which is asynchronous, which means alert(ip_address_2) will always alert undefined.

    Enter Promise and async/await

    Basically, you wrap your code in a Promise and that's what you return. Then outside you await for that promise to resolve/reject and then you'll have your value in ip_address_2.

    Notice I also wrapped the code that invokes getInfo in an IIFE with (important) the async keyword, since await can only be used inside async functions.

    HIH

     function getInfo(website) {
         console.log("getting info...");
         return new Promise(function (resolve, reject) {
            var xhr = new XMLHttpRequest();
            xhr.open("get", website, true);
            xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
            xhr.setRequestHeader("Accept","application/json");
            xhr.setRequestHeader("X-Requested-With","XMLHttpRequest");
    
            xhr.onreadystatechange = function () {
                if (this.readyState == 4 && this.status == 200) {
                   var json = JSON.parse(xhr.responseText);
                   var ip_address = json.ip;
                   resolve(ip_address); //<-- this is how you return (on success) from inside a Promise
                }
                else if (this.readyState == 4 && this.status >= 400 && this.status < 500)
                {
                   reject(this.status); //<-- this is how you return (on failure) from inside a Promise
                   console.log(this.status);
                   console.log("getInfo: readyState == 4 && status >= 400 && status < 500");
                }
                else if (this.readyState == 4 && this.status >= 500)
                {
                   reject(this.status);
                   console.log("getInfo: readyState == 4 && status >= 500");
                }
              }
             xhr.send();
           });
        }
    
    (async ()=>{
        var ip_address_2 = await getInfo("https://cors-anywhere.herokuapp.com/https://api.ipify.org/?format=json&callback=?");
        console.log(`got info: ${ip_address_2}`);
    })();