看看baidu是如何AJAX跨域的 
最近做个人网站遇到AJAX跨子域名的问题。

偶尔看到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这段脚本中还有一些小的技巧也值得我们学习。

总结一句 活学活用 不要钻牛角尖,要不等我们解决ajax跨域的时候花儿也谢了

 
 
 
 

看看baidu是如何AJAX跨域的[转]的更多相关文章

  1. JS跨域(ajax跨域、iframe跨域)解决方法及原理详解(jsonp)

    这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被 ...

  2. Ajax跨域:Jsonp原理解析

    推荐先看下这篇文章:JS跨域(ajax跨域.iframe跨域)解决方法及原理详解(jsonp) JavaScript是一种在Web开发中经常使用的前端动态脚本技术.在JavaScript中,有一个很重 ...

  3. ajax跨域往php程序post数据时,php程序总是执行两次的解决方法

    php程序是部署在IIS7上面,ajax提交数据时,遇到了两个问题,一个就是跨域,一个php程序总会被执行两次. 第一个问题的解决方法,是百度出来的,添加下面几行代码就可以了: header('Acc ...

  4. 以短链服务为例,探讨免AppKey、免认证、Ajax跨域调用新浪微博API

    新浪微博的API官方提供了很多种调用方式,支持编程的,归根结底就是两种: 1.基于Oauth协议,使用Open API.(http://open.weibo.com/wiki/%E6%8E%88%E6 ...

  5. 使用mvc3实现ajax跨域

    ajax跨域一般两种方式   1:cors,2:jsonp, 1:cors jsonp是get形式,承载的信息量有限,所以信息量较大时CORS是不二选择 在请求消息头添头 Access-Control ...

  6. ajax 跨域解决 网上资料

    PHP中运用jQuery的Ajax跨域调用实现代码,需要的朋友可以参考下   可以在页面定义一个调用方法,如下: 复制代码代码如下: function getData(){ $.getJSON(&qu ...

  7. 总结Ajax跨域调用问题

    原文:http://blog.csdn.net/wangxiaohu__/article/details/7294842 (一):动态脚本注入的方法.即在页面中动态生成<script>脚本 ...

  8. 关于Ajax跨域

    本人因工作需求,编写了一个测试页面,在页面填写完信息之后去向一个站点请求数据,然后返回结果!一开始是直接用Ajax在脚本中去访问,没有大碍(因为目标地址是本机上的一个网站),但是当站点去外部的网站时, ...

  9. 百度的一个Ajax跨域方法 JavaScript是没有域的限制

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

随机推荐

  1. BigInteger

    首先上模板(不断更新中...)(根据刘汝佳AOAPCII修改) #include <iostream> #include <sstream> #include <cstd ...

  2. gVim多标签页

    我们一般使用的文本编辑器,如:editplus.ultraEdit等都是支持多标签页的,可以同时打开多个文件,方便切换,以前gVim只能打开多个窗口,或者一个窗口切出多个窗口来编辑,自从7.0以后Vi ...

  3. wamp 提示 Directive allow_call_time_pass_reference is no longer avaiable in PHP

    在wamp运行时,提示"Directive allow_call_time_pass_reference is no longer avaiable in PHP",点击确定之后, ...

  4. 【Slickflow学习】.NET开源工作流项目转换(二)

    第一次自己写博客文章,大家多多指教.写博客主要记录一下学习的过程,给初学者提供下参考,也留给自己做备忘. Slickflow .NET开源工作流-项目转换 上一篇文章里说了1.2版本的下载,下载解压后 ...

  5. jquery mobile 移动web

    轻量级框架jQuery Mobile 所需文件 <link rel="stylesheet" href="jquery.mobile-1.1.2/jquery.mo ...

  6. PS定位

    一.定位:按标准看谁离得近来进行覆盖:什么都没有(最远).浮动(远).定位(近)   二.position absolute 绝对定位,能堆叠在上一层下面,脱离文档流 relative  相对定位,按 ...

  7. .NET通过调用Office组件导出Word文档

    .NET通过调用Office组件导出Word文档 最近做项目需要实现一个客户端下载word表格的功能,该功能是用户点击"下载表格",服务端将该用户的数据查询出来并生成数据到Word ...

  8. ###STL学习--关联容器

    点击查看Evernote原文. #@author: gr #@date: 2014-08-23 #@email: forgerui@gmail.com STL中的关联容器. ###stl学习 |--迭 ...

  9. ###《More Effective C++》- 操作符

    More Effective C++ #@author: gr #@date: 2015-05-21 #@email: forgerui@gmail.com 五.对定制的"类型转换函数&qu ...

  10. PHP - 5.4 Array dereferencing 数组值

    在5.4之前我们直接获取数组的值得方法如下 <?php $str = 'a;b;c;d'; list($value) = explode(';',$str); echo $value; 结果为: ...