1. Question:
var xmlHttp;
function savecarttodata (){
createXMLHttpRequest();
var rndcode = new Date().getTime();
var CartUrl =" a.asp?cache=" rndcode
xmlHttp.onreadystatechange = function() {
.....
}
xmlHttp.open ("GET",CartUrl,true);
xmlHttp.send(null);
}
The above code, xmlHttp.onreadystatechange = function(){.....}; can be executed under FF, but if it is changed to
xmlHttp.open ("GET", Url,false);, it doesn't work. I was confused by this problem today.
Cause analysis:
First: xmlHttp.send() cannot be used at this time, content is required. If there is no content, use NULL
Second: After testing It was found that onreadystatechange is normal under IE, but under FF3, only the code when readyState=0 can be run. The code with readyState=4 cannot be run. I found a reason on the Internet:
The difference in the XMLHttpRequest.onreadystatechange method of ajax: In FF, when the state is 1 (that is, XMLHttpRequest has called open but has not yet called send), FF will continue to execute the code after onreadystatechange. After executing the following code, it will execute the code of onreadystatechange in states 2, 3, and 4, while IE will wait for the arrival of state 2 and finish executing states 2, 3, and 4 of onreadystatechange. After the code, continue to execute the following code, so the problem arises. Often our code in onreadystatechange has to process the data obtained from the server (this data can only be obtained when the status of onreadystatechange is 4), so this is There is no problem in IE because it will wait for the arrival of onreadystatechange status 4 before executing the data after onreadystatechange. However, because FF will not wait until onreadystatechange status 4 arrives before executing the code after onreadystatechange, so the subsequent code cannot process the slave server. What should we do with the data obtained?
Solution: Use JavaScript closures (this solution is inspired by GMAP). We pass a function to onreadystatechange, in which the data returned from the server is processed, but onreadystatechange is a parameterless function, so what should we do? The method of passing parameters has been introduced in my previous Javascript attachEvent. Here I will introduce it a little bit, which is to pass a parameter to onreadystatechange, but use return a no-parameter function in onreadystatechange. You can use this incoming function in this no-parameter function. parameters. This method works fine in both IE and FF, so it is a good method.
The use of closures is mentioned here, which is quite complicated. In addition, there are people on the Internet who use onload under FF, but it does not work. After troubleshooting the error, the reason mentioned in the summary above is the fundamental reason. That is to say, under FF, after executing onreadystatechange for the first time, it continues to execute until send, but it will not go back to execute onreadystatechange later, which is always stupid. Go ahead stupidly.
I changed it directly to:
xmlHttp .onreadystatechange = xmlHandle;
xmlHttp.open ("GET",Url,false);
xmlHttp.send(null);
xmlHttp.onreadystatechange = xmlHandle; //Add a line here to block FF and let it Do it again.
function xmlHandle(){
if (xmlHttp.readyState < 4){
......
}else if (xmlHttp.readyState == 4 && xmlHttp.status == 200){
var cartResult = Number(xmlHttp.responseText);
if (cartResult == 1){
window.location.href='a.asp';
}else if (cartResult == 2){
......;
}else{
window.location.href='/';
}
}
}
But this doesn’t work. Originally ff 3 was changed to: xmlHttp.onreadystatechange = xmlHandle(); However, after adding brackets, IE doesn’t work. Alas, I thought FF was a chicken skin before, but now I feel FF It is purely a title of "supporting standards", but it is a waste of programmer's time. But the program in hand is really important, so I have no choice but to debug it again to see if there is a simpler way, as follows:
xmlHttp.open ("GET",Url,false);
xmlHttp.send(null);
if(xmlHttp.status==200)
xmlHandle();
This code can be used universally under IE and FF. However, since it is a synchronous call, a prompt needs to appear before the result is obtained when readyState < 4, which is very friendly to customers with slow network speeds. However, if you want to obtain this situation while waiting for a response on this machine, due to the fast response of this machine, you will not be able to see the prompt to the customer, so you will not need this code for the time being
Only add browser type analysis.
function getOs()
{
var OsObject = "";
if(navigator.userAgent.indexOf("MSIE")>0) {
return "MSIE"; //IE browser
}
if(isFirefox=navigator .userAgent.indexOf("Firefox")>0){
return "Firefox"; //Firefox browser
}
if(isSafari=navigator.userAgent.indexOf("Safari")> 0) {
return "Safari"; //Safan browser
}
if(isCamino=navigator.userAgent.indexOf("Camino")>0){
return "Camino"; //Camino Browser
}
if(isMozilla=navigator.userAgent.indexOf("Gecko/")>0){
return "Gecko"; //Gecko Browser
}
}
Then change the AJAX code to:
var rndcode = new Date().getTime();
var CartUrl ="a.asp?cache=" rndcode
var btype=getOs();
xmlHttp.onreadystatechange = (btype!="Firefox")?xmlHandle():xmlHandle;
xmlHttp.open ("GET",CartUrl,false);
xmlHttp.send(null);
xmlHttp.onreadystatechange = ( btype!="Firefox")?xmlHandle():xmlHandle;
Example 2
//Get the type of browser to solve the incompatibility problem of onreadystatechange
function getOs()
{
var OsObject = "";
if(navigator.userAgent.indexOf("MSIE")>0) {
return "MSIE"; //IE browser
}
if(isFirefox=navigator.userAgent.indexOf("Firefox ")>0){
return "Firefox"; //Firefox browser
}
if(isSafari=navigator.userAgent.indexOf("Safari")>0) {
return "Safari"; //Safan browser
}
if(isCamino=navigator.userAgent.indexOf("Camino")>0){
return "Camino"; //Camino browser
}
if(isMozilla=navigator.userAgent.indexOf("Gecko/")>0){
return "Gecko"; //Gecko browser
}
}
var objHttp;
function searchCommodityByGroupId(groupId)
{
objHttp = getHttpRequest();
var tt=new Date();
var url="getCommodityListByGroupId.htm?commodityGroupId=" groupId " &time=" tt;
var btype=getOs();
objHttp.onreadystatechange=(btype=="Firefox")?getCommodity():getCommodity;
objHttp.open("GET" ,url,false);
objHttp.send(null);
objHttp.onreadystatechange=(btype=="Firefox")?getCommodity():getCommodity;
}
function getCommodity(){
if(objHttp.readyState==4)
{
if(objHttp.status==200)
{
document.getElementById("commodityDiv").innerHTML=objHttp .responseText;
}
}
}
function getHttpRequest(){
var httpRequest;
if (window.XMLHttpRequest){
httpRequest = new XMLHttpRequest( );
if (httpRequest.overrideMimeType){
httpRequest.overrideMimeType('text/xml');
}
}else if (window.ActiveXObject){
try{
httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
}catch(e){
try {
httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
}catch(e){ }
}
}
return httpRequest;
}