Any way to simulate a *synchronous* XDomainRequest

2019-07-07 12:02发布

问题:

We're making a cross domain call to the google maps geocode API. This was and is working all fine and dandy in modern browsers, but it wasn't working at all in IE8. Looks like it would fail in IE9 as well (partial CORS support). This led to including a XDomainRequest (XDR) to take care of IE8-9. Doing that worked fine in my standalone test to get data back in IE8.

The problem I'm running into now is XDR only works asynchronously so my geocode function returns before my xdr.onload fires.

In my search function, I call the geocode function:

var location = Geocode(city, state);

if (!location) {
    alert('Unable to determine the location of the city and state you entered');
    StopLoading();
    return;
}
//function then uses location.lat and location.lng coordinates

I'm hitting the "Unable to determine location" alert above in IE8.

Here's my geocode function:

Geocode = function (address, state) {
var protocol = location.protocol,
    url = '//maps.googleapis.com/maps/api/geocode/json?sensor=false&address=',
    param = encodeURIComponent(address + ', ' + state),
    json = {};

if ('XDomainRequest' in window && window.XDomainRequest !== null) {
    //IEs that do not support cross domain xhr requests
    var xdr = new XDomainRequest();

    xdr.open('get', protocol + url + param);
    xdr.onload = function() {
        json = jQuery.parseJSON(xdr.responseText);
    };
    xdr.send();
} else {
    //good browsers
    jQuery.ajax({
        url: protocol + url + param,
        type: 'get',
        dataType: 'json',
        async: false,
        success: function(data) {
            json = data;
        }
    });
}

//alert(json);
if (json.status !== 'OK') {
    alert('Unable to determine the location of the city and state you entered');
    return null;
}

return json.results[0].geometry.location;
};

If I comment out the alert(json) in the geocode function, I get my results in IE8 because that's a blocking operation so the request has time to finish and populates my json object. When it's run uncommented, the json object isn't populated.

Anyone have any ideas how I can get this working in IE?

回答1:

asynchron is asynchron. If you want to do something after the request is finished u have to put it into the xdr.onload function.

There is no "wait" function in javascript. You could build one and do a setTimeout loop to check the variable all x-miliseconds. But that would not help u in this case (and its very ugly). In your case you can use the onerror and ontimeout to check if the server had a problem, and the onload to check if the city is in the json.

xdr.onload = function() {
json = jQuery.parseJSON(xdr.responseText);
//check if a city is loaded, go on if true
};
xdr.onerror = function() {
alert('Unable to determine the location of the city and state you entered');
//do whatever u wanna do if something went wrong
xdr.ontimeout = function() {
alert('404 Server');
//do whatever u wanna do if something went wrong
}

i hope this helps you find the way (and by the way, the use of async requests is a much a better way then block the hole javascript/browser ;)

The jQuery doc says:

As of jQuery 1.8, the use of async: false with jqXHR ($.Deferred) is deprecated; you must use the success/error/complete callback options instead of the corresponding methods of the jqXHR object such as jqXHR.done() or the deprecated jqXHR.success()