zoukankan      html  css  js  c++  java
  • JavaScript是没有域的限制

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

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

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

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

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

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

  • 相关阅读:
    集合赋值及for循环删除符合条件的元素
    shiro系列12:rememberme(记住我)
    shiro系列11:缓存
    shiro系列10:会话管理
    shiro系列8:授权源码解析
    shiro系列7:拦截器
    shiro系列6:授权
    shiro系列5:Realm
    shiro系列4:认证源码解析
    shiro系列3:MD5盐值加密认证流程
  • 原文地址:https://www.cnblogs.com/xiaoyang002/p/4106893.html
Copyright © 2011-2022 走看看