1

I am trying to detect the user's city via this website: http://www.ipaddresslocation.org/my-ip-address.php. Almost all of the free geolocation APIs I've seen so far were not very accurate. When the following code executes, I see all the information I need in the Response tab (in the Network tab in Firefox), but the success event fails and I am not able to access any of that data.

$(document).ready(function(){                    
   getCity(); 
});

var parameters = {
  "Content-Type": "text/html",
  'Accept-Encoding': 'gzip, deflate',
};

function getCity() {

    $.ajax({
      type: "GET",
      url: 'http://www.ipaddresslocation.org/ip-address-locator.php',
      dataType: 'jsonp',
      success: function(data) {
        console.log("success");
      },
      error: function(xhr, status, error) {
        console.log("ERROR");
        console.log(error.message);
      }
    });
}

enter image description here

enter image description here

enter image description here

Autumn
  • 223
  • 3
  • 15
  • 1
    Try implementing a purposed error (like on the url), to see if you go inside the error callback. If you don't, you will know the problem lies there, and you can come back here and answer me. – Ted Jul 25 '15 at 01:14
  • Do you mean doing a test to check if the url is broken? When I run this in codepen, the error message gets printed, but I am getting the correct location in the Firefox request window. – Autumn Jul 25 '15 at 01:26
  • Yes that's what I meant. Can you upload a screenshot with what returns in your Firefox? – Ted Jul 25 '15 at 01:27

2 Answers2

1

The problem with my code was that I was trying to get the server to respond when I just needed to read the HTML page in my browser. Because of the Same Origin policy, I ended up using the CORS Anywhere node.js proxy to add headers to the proxied request and then doing RegEx to get the city. This link is great at explaining how to make cross-domain requests: Loading cross domain endpoint with jQuery AJAX .

$(document).ready(function() {

  $.ajaxPrefilter(function(options) {
    if (options.crossDomain && jQuery.support.cors) {
      var http = (window.location.protocol === 'http:' ? 'http:' : 'https:');
      options.url = http + '//cors-anywhere.herokuapp.com/' + options.url;
    }
  });

  $.get(
    'http://www.ipaddresslocation.org/ip-address-locator.php',
    function(response) {
      //regex to get the desired info
    });

});
Community
  • 1
  • 1
Autumn
  • 223
  • 3
  • 15
0

This happens when third party APIs haven't set things up developer-friendly. You can use the complete callback instead of the success callback and then access the responseText property of the XHR response:

$(document).ready(function(){                    
   getCity(); 
});

var parameters = {
  "Content-Type": "text/html",
  'Accept-Encoding': 'gzip, deflate',
};

function getCity() {

    $.ajax({
      type: "GET",
      url: 'http://www.ipaddresslocation.org/ip-address-locator.php',
      dataType: 'jsonp',
      complete: function(jqXHR, txtStatus) {
        var myData = jqXHR.responseText;
      },
      error: function(xhr, status, error) {
        console.log("ERROR");
        console.log(error.message);
      }
    });
}

http://api.jquery.com/jquery.ajax/

swatkins
  • 13,530
  • 4
  • 46
  • 78
  • It looks like myData is undefined and the error message still gets printed to the console. I have no idea why that is. – Autumn Jul 25 '15 at 04:28
  • 1
    It's just the way the API is returning. Could you do a `console.log(jqXHR);` in the complete callback? That will tell you what properties are available there and where those data are. – swatkins Jul 25 '15 at 04:31
  • I'm able to see all of its properties. It looks like I cannot retrieve anything from the HTML file shown in the response because this object doesn't have a property to do so. Is that right or am I overlooking something? ( Object { readyState: 4, getResponseHeader: .ajax/v.getResponseHeader(), getAllResponseHeaders: .ajax/v.getAllResponseHeaders(), setRequestHeader: .ajax/v.setRequestHeader(), overrideMimeType: .ajax/v.overrideMimeType(), statusCode: .ajax/v.statusCode(), abort: .ajax/v.abort(), state: .Deferred/d.state(), always: .Deferred/d.always(), then: .Deferred/d.then(), 10 more… }). – Autumn Jul 25 '15 at 05:08
  • What you see in the response tab should be available in `jqXHR.responseText`. You don't see that as an option? – swatkins Jul 25 '15 at 05:14
  • Maybe it should by synchronous? have a look at this answer: http://stackoverflow.com/a/5472371/844726 – swatkins Jul 25 '15 at 05:16
  • responseText is not one of the keys. For most of the prop, obj[key] returns "function ()". Check it out codepen.io/veronikabenkeser/pen/qdJrxo . Just tried experimenting with making it synchronous, but nothing has change. I think this "responeText and responseXml are only polulated when using dataType: text or xml. If you use any other data types it will be passed as the first param in your success callback" may be the problem because my callback function fails. – Autumn Jul 25 '15 at 16:10