百度的一个Ajax跨域方法 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这段脚本中还有一些小的技巧也值得我们学习。
相关文章:
AJAX 跨域请求 - JSONP获取JSON数据
jsonp是什么以及jsonp的使用
百度的一个Ajax跨域方法 JavaScript是没有域的限制的更多相关文章
- jquery ajax跨域的完美解决方法(jsonp方式)
ajax跨域请求的问题,JQuery对于Ajax的跨域请求有两类解决方案,不过都是只支持get方式,接下来为大家详细介绍下客户端JQuery.ajax的调用代码 今天在项目中需要做远程数据加载 ...
- ajax 跨域的问题 用js绕过跨域
之前遇到一个ajax跨域的问题,搜索了很多方法才找到解决方案,也怪自己 菜鸟一个 这些经验还是要慢慢来的 尤其是最近来回顾一下 竟然发现自己忘记了 所以还是把它记下来啊 免得到时候忘记 这个方法原 ...
- 简单ajax跨域请求
最近遇到需要ajax跨域的需求 首先看下不做任何处理特别处理的ajax跨域请求会出现什么样的错误 客户端代码: <script type="text/javascript"& ...
- JQuery的Ajax跨域请求原理概述及实例
今天在项目中需要做远程数据加载并渲染页面,直到开发阶段才意识到ajax跨域请求的问题,隐约记得Jquery有提过一个ajax跨域请求的解决方式,于是即刻翻出Jquery的API出来研究,发 JQuer ...
- [转载]JQuery的Ajax跨域请求的解决方案
今天在项目中需要做远程数据加载并渲染页面,直到开发阶段才意识到ajax跨域请求的问题,隐约记得Jquery有提过一个ajax跨域请求的解决方式,于是即刻翻出Jquery的API出来研究,发现JQuer ...
- 手机端-ajax跨域请求滚屏分页
近期做了一个关于信息展示的详情页面,将里面能够提升用户体验的小点写出来 1.当页面请求新的数据,或上传数据的时候 放一个loading.gif的过渡,告诉用户 你的操作已经完成,正在加载中 2.当所有 ...
- JQuery的Ajax跨域请求的解决方式
今天在项目中须要做远程数据载入并渲染页面,直到开发阶段才意识到ajax跨域请求的问题,隐约记得Jquery有提过一个ajax跨域请求的解决方式,于是即刻翻出Jquery的API出来研究 ...
- 解决ajax跨域的方法原理详解之Cors方法
1.神马是跨域(Cross Domain) 对于端口和协议的不同,只能通过后台来解决. 一句话:同一个ip.同一个网络协议.同一个端口,三者都满足就是同一个域,否则就是 跨域问题了.而为什么开 ...
- ASP.NET MVC 实现AJAX跨域请求方法《1》
ASP.NET MVC 实现AJAX跨域请求的两种方法 通常发送AJAX请求都是在本域内完成的,也就是向本域内的某个URL发送请求,完成部分页面的刷新.但有的时候需要向其它域发送AJAX请求,完成数据 ...
随机推荐
- codeforces 212E IT Restaurants(树形dp+背包思想)
题目链接:http://codeforces.com/problemset/problem/212/E 题目大意:给你一个无向树,现在用两种颜色去给这颗树上的节点染色.用(a,b)表示两种颜色分别染的 ...
- lost connection to mysql server reading initial communication packet
- google、baidu高级搜索技巧
1.baidu(可以去高级搜索查看更多信息) intitle搜索范围限定在网页标题:intitle:和后面的关键词之间不要有空格----intitle:中国 site搜索范围限定在特定站点中:“sit ...
- linux 监控命令
先总结下常用的一些监控工具: ##linux命令 w 系统负载 lsof -p pid 进程打开的文件 lsof -i:port 端口的运行情况 free -m 内存情况 vmstat 进程.内存.内 ...
- c#基础语言编程-序列化
引言 程序员在编写应用程序的时候往往要将程序的某些数据存储在内存中,然后将其写入某个文件或是将它传输到网络中的另一台计算机上以实现通讯.这个将程序数据转化成能被存储并传输的格式的过程被称为" ...
- PDF模板报表导出(Java+Acrobat+itext)
1. 首先要安装Adobe Acrobat,装好之后用Acrobat从一个word,excel或者pdf中转换一个pdf模板,我做的模板很简单,直接写一个简单的word再生成一个pdf表单,之后编辑文 ...
- 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(46)-工作流设计-设计分支
原文:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(46)-工作流设计-设计分支 系列目录 步骤设置完毕之后,就要设置好流转了,比如财务申请大于50000元( ...
- 通过WriteProcessMemory改写进程的内存
http://www.cnblogs.com/feiyucq/archive/2009/10/21/1587628.html 以PROCESS_ALL_ACCESS权限打开进程以后既能够使用ReadP ...
- android 52 粘滞广播
粘滞广播:广播发送出去以后,广播接收者还没有创建,当广播接收者注册的时候就可以接收,如果不是粘滞广播则如果没有广播接收者就以后不能再接收了. mainActivity: package com.sxt ...
- PowerDesigner15的安装和破解
一.PowerDesigner15的安装 运行安装包,出现如下安装界面