>웹 프론트엔드 >JS 튜토리얼 >firefox_javascript 기술에 따른 ajax의 onreadystatechange 지원 분석

firefox_javascript 기술에 따른 ajax의 onreadystatechange 지원 분석

WBOY
WBOY원래의
2016-05-16 18:39:08872검색

1. 질문:

코드 복사 코드는 다음과 같습니다.

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)
}; 🎜>

위 코드 xmlHttp.onreadystatechange = function(){.....}은 FF에서도 실행이 가능하지만,

xmlHttp.open(" GET", Url,false); 작동하지 않습니다. 오늘 이 문제로 인해 혼란스러워졌습니다.

원인 분석:

첫 번째: xmlHttp.send()를 현재 사용할 수 없으므로 콘텐츠가 필요하면 NULL을 사용하세요.

두 번째: 이후. 테스트 IE에서는 onreadystatechange가 정상이지만 FF3에서는 ReadyState=0일 때의 코드만 실행할 수 있는 것으로 나타났습니다. ReadyState=4인 코드를 실행할 수 없습니다. 인터넷에서 이유를 찾았습니다.
ajax의 XMLHttpRequest.onreadystatechange 메소드의 차이점: FF에서 상태가 1인 경우(즉, XMLHttpRequest가 open을 호출했지만 아직 send라고 호출되지 않음), FF는 onreadystatechange 이후에 코드를 계속 실행합니다. 다음 코드를 실행한 후 상태 2, 3, 4에서 onreadystatechange 코드를 실행하는 반면 IE는 상태 2가 도착할 때까지 기다리고 완료합니다. onreadystatechange의 상태 2, 3, 4를 실행한 후 다음 코드를 계속 실행하면 문제가 발생합니다. 종종 onreadystatechange의 코드는 서버에서 얻은 데이터를 처리해야 합니다(이 데이터는 onreadystatechange의 상태는 4)이므로 이는 onreadystatechange 이후 데이터를 실행하기 전에 onreadystatechange 상태 4가 도착할 때까지 기다리므로 IE에서는 문제가 없습니다. 그러나 FF는 코드를 실행하기 전에 onreadystatechange 상태 4가 도착할 때까지 기다리지 않기 때문입니다. onreadystatechange 이후에 후속 코드가 슬레이브 서버를 처리할 수 없게 되면 얻은 데이터로 어떻게 해야 합니까?

해결책: JavaScript 클로저를 사용하세요(이 솔루션은 GMAP에서 영감을 얻었습니다). 서버에서 반환된 데이터를 처리하는 함수를 onreadystatechange에 전달하는데, onreadystatechange는 매개변수가 없는 함수이므로 어떻게 해야 할까요? 매개변수 전달 방법은 이전 Javascript attachmentEvent에서 소개되었습니다. 여기서는 onreadystatechange에 매개변수를 전달하지만 onreadystatechange에서 매개변수 없는 함수를 반환하는 방법을 조금 소개하겠습니다. 이 매개변수 없는 함수입니다. 이 방법은 IE와 FF 모두에서 잘 작동하므로 좋은 방법입니다.

여기서 클로저 사용에 대해 언급했는데 꽤 복잡합니다. 게다가 인터넷에 FF 하에서 onload를 사용하는 사람들도 있는데 작동하지 않습니다. 오류를 해결한 후 위 요약에서 언급한 이유가 근본적인 이유입니다. 즉, FF에서는 처음 onreadystatechange를 실행한 후 보내기 전까지 계속 실행되지만 나중에 다시 onreadystatechange를 실행하지 않는 것입니다. , 항상 어리석은 일입니다.

직접 변경했습니다:


xmlHttp .onreadystatechange = xmlHandle;
xmlHttp.open ("GET",Url,false)
xmlHttp.send(null)
xmlHttp.onreadystatechange = xmlHandle; 여기에서 FF를 차단하고 다시 하도록 하세요.


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='/';
}
}
}


그러나 이것은 작동하지 않습니다. 원래 ff 3은 다음과 같이 변경되었습니다. xmlHttp.onreadystatechange = xmlHandle(); 그러나 괄호를 추가한 후 IE는 작동하지 않습니다. 이전에는 치킨 스킨이었는데 지금은 FF 느낌이 듭니다. 순전히 "표준 지원"이라는 제목이지만 프로그래머의 시간 낭비입니다. 하지만 손에 있는 프로그램이 정말 중요하기 때문에 더 간단한 방법이 있는지 알아보기 위해 다시 디버깅할 수밖에 없습니다.


코드를 복사하세요 코드는 다음과 같습니다.
xmlHttp.open ("GET",Url,false)
xmlHttp.send(null)
if (xmlHttp.status==200)
xmlHandle()


이 코드는 IE와 FF에서 보편적으로 사용할 수 있습니다. 그러나 동기식 호출이기 때문에 ReadyState < 4일 때 결과를 얻기 전에 프롬프트가 나타나야 하는데, 이는 네트워크 속도가 느린 고객에게 매우 친화적입니다. 그러나 이 기계에서 응답을 기다리는 동안 이런 상황을 얻고자 한다면 이 기계의 빠른 응답으로 인해 고객에게 프롬프트를 볼 수 없으므로 당분간 이 코드가 필요하지 않습니다.

브라우저 유형 분석만 추가하세요.
코드 복사 코드는 다음과 같습니다.

function getOs()
{
var OsObject = "";
if(navigator.userAgent.indexOf("MSIE")>0) {
return "MSIE"; //IE 브라우저
}
if(isFirefox =navigator .userAgent.indexOf("Firefox")>0){
return "Firefox"; //Firefox 브라우저
}
if(isSafari=navigator.userAgent.indexOf("Safari")> ; 0) {
return "Safari"; //사판 브라우저
}
if(isCamino=navigator.userAgent.indexOf("Camino")>0){
return "Camino"; //카미노 브라우저
}
if(isMozilla=navigator.userAgent.indexOf("Gecko/")>0){
return "Gecko"; //Gecko 브라우저
}
}

그런 다음 AJAX 코드를 다음과 같이 변경합니다.
코드 복사 코드는 다음과 같습니다.

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); = ( btype!="Firefox")?xmlHandle():xmlHandle;

예제 2

코드 복사 코드는 다음과 같습니다.
//onreadystatechange의 비호환 문제를 해결하기 위해 브라우저 유형을 가져옵니다.
function getOs()
{
var OsObject = " ";
if(navigator.userAgent.indexOf("MSIE")>0) {
return "MSIE"; //IE 브라우저
}
if(isFirefox=navigator.userAgent.indexOf ("Firefox")>0){
return "Firefox"; //Firefox 브라우저
}
if(isSafari=navigator.userAgent.indexOf("Safari")>0) {
return "Safari"; //사판 브라우저
}
if(isCamino=navigator.userAgent.indexOf("Camino")>0){
return "Camino"; >}
if(isMozilla=navigator.userAgent.indexOf("Gecko/")>0){
return "Gecko"; //Gecko 브라우저
}
}
var objHttp ;
function searchCommodityByGroupId(groupId)
{
objHttp = getHttpRequest();
var tt=new Date()
var url="getCommodityListByGroupId.htm?commodityGroupId " &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){ }
}
}
httpRequest 반환
}

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.