简体   繁体   中英

Understanding XHR request object in javascript... (confused)

I'm following a simple book and It says:

function createRequest() 
{ 
    try 
    {  
        request = new XMLHttpRequest(); 
    } 
    catch (tryMS) 
    {  
        try 
        {   
            request = new ActiveXObject("Msxml2.XMLHTTP");  
        } 
        catch (otherMS) 
        {   
        try 
        {    
            request = new ActiveXObject("Microsoft.XMLHTTP");   
        } 
        catch (failed) 
        {    
            request = null;   
        }   
        }
    } 
 return request; 
 } 

function getDetails(itemName) 
{ 
    var request = createRequest();
    if (request==null) 
    {    alert("Unable to create request");  
        return;  
    } 
    var url= "getDetails.php?ImageID=" +    escape(itemName); 
    request.open("GET",url,true);  
    request.onreadystatechange = displayDetails; 
    request.send(null); 
}


function displayDetails() 
{  
    if (request.readyState == 4) 
    {    
        if (request.status == 200) 
        {      
            detailDiv = document.getElementById("description");      
            detailDiv.innerHTML = request.responseText;    
        }  
    } 
}

And all this code above is fine and it's okay to me.. but after few pages it says:

ITS VERY IMPORTANT TO REMOVE VAR KEYWORD BEFORE request VARIABLE so the callback can reference the variable...

but how come in example above it worked? is it coincidence if we call a variable 'request' that it will map with global variable in a createRequest method?

Take a look on image below:

在此处输入图片说明

Why is this happening ? in one example var before request variable is used and everything is fine, in another var is avoided so the method in callback might access it.. but how come method in a callback is accessing a request variable in first example...

It's confusing because there are 2 similar examples, with different explanations..

EDIT PS it says request has to be a global ? :o

在此处输入图片说明

Thanks guys Cheers

In both examples, implicit global variables are created so they can be shared with the callback. When the second request variable is created, it creates a local variable inside the getDetails function. So when createRequest() returns the global variable, the local variable becomes a reference to it.

This is rather bad advice and shows a lack of understanding on the writers' part. But it seems to be an old text, since activeX objects are deprecated by now, so maybe globals used to be less frowned upon. The proper way is to either send the responseText or responseXML as a parameter to the callback or send the entire request as the parameter for the callback.

Maybe the writer didn't want to make the request code more complex, but imho, this is not a good way to teach people things.

function createRequest( method, url, callback, payload ) {
    var request = new XMLHttpRequest();
    if ( !request ) {
        alert( "Unable to create request" );  
        return null;
    }
    request.open( method, url );
    request.onreadystatechange = function() {
        if (request.readyState === 4 && request.status === 200 ) {
            callback( request.responseText );
        }
    };
    request.send( payload );
};
function getDetails( itemName, callback ) {
    createRequest( "GET", "getDetails.php?ImageID=" + escape(itemName), callback, null );
};
function displayDetails( detail ) {
    var detailDiv = document.getElementById("description");      
    detailDiv.innerHTML = detail;
};
getDetails( "someItemName", displayDetails );

you are right, in your first example, function createRequest is not using var , which mean you are creating a global variable request when excute request = new XMLHttpRequest(); .

We should avoid using gobal var in most situation.

function createRequest() {
    try {
        // add var so it's not global variable
        var request = new XMLHttpRequest();
    } catch (tryMS) {
        try {
            request = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (otherMS) {
            try {
                request = new ActiveXObject("Microsoft.XMLHTTP");
            } catch (failed) {
                request = null;
            }
        }
    }
    return request;
}

function getDetails(itemName) 
{ 
    var request = createRequest();
    if (request==null) 
    {    alert("Unable to create request");  
        return;  
    } 
    var url= "getDetails.php?ImageID=" +    escape(itemName); 
    request.open("GET",url,true);  

    // create anonymous function to call your callback and pass `request` as local variable
    request.onreadystatechange = function(){
        displayDetails(request);
    }; 
    request.send(null); 
}

function displayDetails(request) 
{  
    if (request.readyState == 4) 
    {    
        if (request.status == 200) 
        {      
            detailDiv = document.getElementById("description");      
            detailDiv.innerHTML = request.responseText;    
        }  
    } 
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM