Ajax 跨域解决方法


 

baidu的通行证处理都是在二级域名passport.baidu.com中处理的,但是baidu很多地方登录都好像是用ajax处理的,他是怎么做的呢?研究了一下,发现一个小技巧。

在http://zhidao.baidu.com/ 未登录用户回答问题时会用iframe调用http://zhidao.baidu.com/userlogin.html,userlogin.html 有下面的 javascript:

01 <SCRIPT LANGUAGE= "JavaScript" >
02 document.domain= "baidu.com" ;
03 <!--
04 function G(id){ if ( typeof (id)== "string" ){ return document.getElementById(id);} return id;}
05 function showInfo(obj){
06      if (obj.checked == true ){
07          G( "memInfo" ).style.display= "block" ;
08      } else {
09          G( "memInfo" ).style.display= "none" ;
10      }
11 }
12 function request(id,url){
13       oScript = document.getElementById(id);
14       var head = document.getElementsByTagName( "head" ).item(0);
15       if (oScript) {
16          head.removeChild(oScript);
17       }
18       oScript = document.createElement( "script" );
19       oScript.setAttribute( "src" , url);
20       oScript.setAttribute( "id" ,id);
21       oScript.setAttribute( "type" , "text/javascript" );
22       oScript.setAttribute( "language" , "javascript" );
23       head.appendChild(oScript);
24       return oScript;
25 }
26 var loginTimer= null ;
27 var loginState=-1;
28 var tryTime=0;
29 function PSP_ik(isOk){
30      if (isOk==0){
31          G( "errorInfo" ).style.display= "none" ;
32          loginState=1;
33          if (parent.loginSuccess){
34              parent.Pop.hide();
35              parent.loginSuccess();
36          }
37      }
38      else
39      {
40          loginFalse();
41      }
42 }
43  
44 function loginFalse(){
45      loginState=0;
46      var err=G( "errorInfo" );
47      err.innerHTML= "用户名或密码错误,请重新登录" ;
48      err.style.display= "block" ;
49      G( "username" ).focus();
50      tryTime++;
51      if (tryTime>1){
52          onLoginFailed();
53      }
54 }
55 function onLoginFailed(){
56      if (parent.onLoginFailed){
57          parent.Pop.hide();
58          parent.loginFailed();
59      } else {
60          document.login.u.value=escape( "http://zhidao.baidu.com/q " +parent.location.search);
61          doucment.login.submit();
62      }
63           
64 }
65 function loginTimeout(){
66      if (loginState==-1){
67          var err=G( "errorInfo" );
68          err.innerHTML= "操作超时,请重新登录" ;
69          err.style.display= "block" ;
70          G( "username" ).focus();
71      }
72 }
73 function userLogin(){
74      var username=G( 'username' ).value;
75      var password=G( 'password' ).value;
76      var memPassport=G( 'memPassport' ).checked? "on" : "off" ;
77      if (username.length<=0||password.length<=0){G( "username" ).focus(); return false ;}
78      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();
79      loginState=-1;
80      var login=request( "loginScript" ,url);
81      loginTimer = setTimeout(loginTimeout, 5000);
82  
83 }
84 window.onload= function (){
85      document.loginForm.username.focus();   
86      document.getElementById( "username" ).focus();
87 }
88 //-->
89 </SCRIPT>

我们可以看到request方法处理异步请求使用动态往head中添加script而不是用xmlhttp发送get请求。妙就妙在这。我们知道调用javascript是没有域的限制的。当加载完成时一样会执行。

当然请求参数只能通过拼url的方式了。url通过服务器处理后直接输出loginFalse()或者PSP_ik();非常优雅的解决了跨域的问题。

这让我们想到了用iframe当ajax上传文件一样异曲同工。如果不需要服务器反馈,google的点击计数用new img().src=...;

当然baidu这段脚本中还有一些小的技巧也值得我们学习。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值