建站學(xué)院(LieHuo.Net)AJAX教程 大家在做網(wǎng)站時可能會遇到AJAX跨子域名的問題,這個問題對于技術(shù)高手來說可能并不難,但是對于新手來說可能是難題了,偶爾看到baidu的通行證處理都是在二級域名passport.baidu.com中處理的,但是baidu很多地方登錄都好像是用ajax處理的,他是怎么做的呢?研究了一下,發(fā)現(xiàn)一個小技巧。 咱們也借鑒一下。
在http://zhidao.baidu.com/ 未登錄用戶回答問題時會用iframe調(diào)用http://zhidao.baidu.com/userlogin.html,userlogin.html有下面的javascript,代碼如下:
以下為引用的內(nèi)容: <SCRIPT LANGUAGE="JavaScript"> document.domain="baidu.com"; <!-- function G(id){if(typeof(id)=="string"){return document.getElementById(id);}return id;} function showInfo(obj){ if(obj.checked == true){ G("memInfo").style.display="block"; }else{ G("memInfo").style.display="none"; } } function request(id,url){ oScript = document.getElementById(id); var head = document.getElementsByTagName("head").item(0); if (oScript) { head.removeChild(oScript); } oScript = document.createElement("script"); oScript.setAttribute("src", url); oScript.setAttribute("id",id); oScript.setAttribute("type","text/javascript"); oScript.setAttribute("language","javascript"); head.appendChild(oScript); return oScript; } var loginTimer=null; var loginState=-1; var tryTime=0; function PSP_ik(isOk){ if(isOk==0){ G("errorInfo").style.display="none"; loginState=1; if(parent.loginSuccess){ parent.Pop.hide(); parent.loginSuccess(); } } else { loginFalse(); } } function loginFalse(){ loginState=0; var err=G("errorInfo"); err.innerHTML="用戶名或密碼錯誤,請重新登錄"; err.style.display="block"; G("username").focus(); tryTime++; if(tryTime>1){ onLoginFailed(); } } function onLoginFailed(){ if(parent.onLoginFailed){ parent.Pop.hide(); parent.loginFailed(); }else{ document.login.u.value=escape("http://zhidao.baidu.com/q"+parent.location.search); doucment.login.submit(); } } function loginTimeout(){ if(loginState==-1){ var err=G("errorInfo"); err.innerHTML="操作超時,請重新登錄"; err.style.display="block"; G("username").focus(); } } function userLogin(){ var username=G('username').value; var password=G('password').value; var memPassport=G('memPassport').checked?"on":"off"; if(username.length <=0||password.length <=0){G("username").focus();return false;} var url = 'https://passport.baidu.com/?logt&tpl=ik&t=0&keyname=ik&mem_pass='+memPassport+'&username='+username + '&loginpass=' +escape(password)+ '&s=' + (new Date()).getTime(); loginState=-1; var login=request("loginScript",url); loginTimer = setTimeout(loginTimeout, 5000); } window.onload=function(){ document.loginForm.username.focus(); document.getElementById("username").focus(); } //--> </SCRIPT> |
我們可以看到request方法處理異步請求使用動態(tài)往head中添加script而不是用xmlhttp發(fā)送get請求。妙就妙在這。我們知道調(diào)用javascript是沒有域的限制的。當(dāng)加載完成時一樣會執(zhí)行。當(dāng)然請求參數(shù)只能通過拼url的方式了。url通過服務(wù)器處理后直接輸出loginFalse()或者PSP_ik();
非常優(yōu)雅的解決了跨域的問題。
這讓我們想到了用iframe當(dāng)ajax上傳文件一樣異曲同工。 如果不需要服務(wù)器反饋,google的點(diǎn)擊計(jì)數(shù)用new img().src=...; 當(dāng)然baidu這段腳本中還有一些小的技巧也值得我們學(xué)習(xí)。