AJAX案例研究之Gmail

本文主要剖析了Gmail的AJAX应用实现。先介绍了Gmail主框架网页兼浏览器检测页,通过检测后会写框架代码。接着分析了js框架的javascript代码及Google编码风格,还指出Gmail处理返回信息仅用基本responseText,cgi生成js脚本或文本信息,使其能跨浏览器,且该应用几乎未用xml。

现在提起AJAX,大家都立刻会想起Gmail、gogle map这几个经典的AJAX应用。Gmail的优良表现我们都看过了,那么它的实现你研究过了吗?它怎么在几个不同的浏览器上可以一致的实现xml异步调用的呢?一起来看看吧。

首先,登录gmail以后我们会先进入这个页面:

<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="content-type">
<title>Gmail</title>
<link rel="alternate" type="application/atom+xml" title="Gmail Atom Feed" href="feed/atom" />
<script src="?view=page&name=browser&ver=c0d3d44c64799453"></script>
</head>
<noscript>
<font face=arial>
应启用 JavaScript,才能在标准视图中使用 Gmail。然而,JavaScript 似乎已被禁用,要么就是您的浏览器不支持 JavaScript。要使用标准视图,请更改您的浏览器选项以启用 JavaScript,然后<a href="">重试</a>。<p>要使用 Gmail 的基本 HTML 视图(不需要 JavaScript),<a href="?ui=html&zy=n">请单击此处</a>。</p>
</font>
</noscript>
<script>
<!--
var fs_time = (new Date()).getTime();
function wfs() {
try {
if (parent != window && parent.wfs) {
return false;
}
} catch(e) {
}
if (top.location.href.indexOf('nocheckbrowser') != -1) {
return true;
}
if (!is_browser_supported) {
top.location = '?ui=html&zy=j';
return false;
}
var testcookie = 'jscookietest=valid';
document.cookie = testcookie;
if (document.cookie.indexOf(testcookie) == -1) {
top.location = 'html/zh-CN/nocookies.html';
return false;
}
document.cookie = testcookie + ';expires=' + new Date(0).toGMTString();
var agt = navigator.userAgent.toLowerCase();
if (agt.indexOf('msie')!= -1 && document.all &&agt.indexOf('opera') == -1 && agt.indexOf('mac') == -1) {
eval("var control = (agt.indexOf('msie 5') != -1) ? 'Microsoft.XMLHTTP' : 'Msxml2.XMLHTTP';try {new ActiveXObject(control);} catch (e) {top.location = 'html/zh-CN/noactivex.html';}");
}
return true;
}
function lj() {
js.location.replace('?view=page&name=js&ver=d6079057e81abd3c');
}
if (wfs()) {
document.write("<frameset onload=lj() rows=\"100%,*\" border=0><frame name=main src=html/zh-CN/loading.html frameborder=0 noresize scrolling=no><frame name=js src=html/zh-CN/loading.html frameborder=0 noresize></frameset>");}
//-->
</script>
</html>

这是主框架网页兼浏览器检测页。如果浏览器通过了检测(支持javascript、cookie和xml控件)则在页面上写一段框架代码

要注意到的是google在这里耍了一个小花招,那个叫做main的框架页面里面看来没有多少东西,好东东都在那个叫js的框架里面呢。

我们接着把这个js框架拉出来看看:

整整1500多行的javascript代码!

这个页面有240多k,几乎全都是javascript代码。有兴趣分析的兄弟姐妹们请点这里下载

其实其中大部分都是老生常谈的js代码了,不过我们可以一窥google的编码风格:尽可能压缩信息量,变量名能用一个字母的绝不用两个,函数名一概都是两个字母的,函数内的会车是没有的,缩进也是没有的。虽然代码没有特地加密,但是如此处理一番之后也就没什么可读性了。还好系统的关键字是不能缩水的,顺着xml控件的名字我们可以揪出来跟AJAX异步加载数据相关的几个关键函数:

function vb(){ var a = null ; if (r){ var b = fG ? " Microsoft.XMLHTTP " : " Msxml2.XMLHTTP " ; try {a = new ActiveXObject(b)} catch (c){q(c);alert( " 您需要启用活动脚本功能和activeX控件。 " )}} else {a = new XMLHttpRequest(); if ( ! a){;alert( " 此浏览器不支持XMLHttpRequest。 " )}} return a}
// emu注释构造XML控件并返回给调用者

function ot(a,b){; try {a.send(b)} catch (c){q(c); if (c.number ==- 2146697208 ){alert( " 请确保InternetExplorer的”语言”设置部分不是空白。 " )}}}
// emu注释执行发送数据操作a:XML控件b:要发送的数据

function Wf(a,b,c){Da( 3 );b = Ld(b);Hf(a,b,c)}
// emu注释a:XML控件b:访问的urlc:回调函数Da是验证参数长度的函数
//
Ld是一个url转换加工的函数,主要处理url自带的CGI参数和翻页的页数等

function Hf(a,b,c){Da( 3 );a.onreadystatechange = c;a.open( " GET " ,b, true );ot(a, null )}
// emu注释不发送数据直接请求资源a:XML控件b:访问的urlc:回调函数

function nt(a,b,c,d){Da( 4 );a.onreadystatechange = d;a.open( " POST " ,b, true );ot(a,c)}
// emu注释发送数据并请求资源a:XML控件b:访问的urlc:要发送的数据d:回调函数

基本上就这么多了,很失望吧,没有什么新鲜的东西。发送http请求之后它又怎么处理返回的xml的呢?事实上他没有处理。他所处理的仅仅是最基本responseText,而cgi则直接生成js脚本到客户端回调(用eval运行),或者生成文本信息。这就是为什么gmail可以轻松跨域几个浏览器了。

作为最受推崇的一个AJAX应用,却几乎没有用到xml。像这样用xml控件来收发文本信息后在页面上展现的技术,基本上就是现在AJAX最流行的应用方式了,不过这样也能叫AJAX吗?我宁可就叫它AJ,最多叫AJAH。

今天先到这,下回再过来分析另一个完全不同的AJAX应用吧。大家周末愉快!

function vb(){ var a = null ; if (r){ var b = fG ? " Microsoft.XMLHTTP " : " Msxml2.XMLHTTP " ; try {a = new ActiveXObject(b)} catch (c){q(c);alert( " 您需要启用活动脚本功能和activeX控件。 " )}} else {a = new XMLHttpRequest(); if ( ! a){;alert( " 此浏览器不支持XMLHttpRequest。 " )}} return a}
// emu注释构造XML控件并返回给调用者

function ot(a,b){; try {a.send(b)} catch (c){q(c); if (c.number ==- 2146697208 ){alert( " 请确保InternetExplorer的”语言”设置部分不是空白。 " )}}}
// emu注释执行发送数据操作a:XML控件b:要发送的数据

function Wf(a,b,c){Da( 3 );b = Ld(b);Hf(a,b,c)}
// emu注释a:XML控件b:访问的urlc:回调函数Da是验证参数长度的函数
//
Ld是一个url转换加工的函数,主要处理url自带的CGI参数和翻页的页数等

function Hf(a,b,c){Da( 3 );a.onreadystatechange = c;a.open( " GET " ,b, true );ot(a, null )}
// emu注释不发送数据直接请求资源a:XML控件b:访问的urlc:回调函数

function nt(a,b,c,d){Da( 4 );a.onreadystatechange = d;a.open( " POST " ,b, true );ot(a,c)}
// emu注释发送数据并请求资源a:XML控件b:访问的urlc:要发送的数据d:回调函数

基本上就这么多了,很失望吧,没有什么新鲜的东西。发送http请求之后它又怎么处理返回的xml的呢?事实上他没有处理。他所处理的仅仅是最基本responseText,而cgi则直接生成js脚本到客户端回调(用eval运行),或者生成文本信息。这就是为什么gmail可以轻松跨域几个浏览器了。

作为最受推崇的一个AJAX应用,却几乎没有用到xml。像这样用xml控件来收发文本信息后在页面上展现的技术,基本上就是现在AJAX最流行的应用方式了,不过这样也能叫AJAX吗?我宁可就叫它AJ,最多叫AJAH。

今天先到这,下回再过来分析另一个完全不同的AJAX应用吧。大家周末愉快!

整整1500多行的javascript代码!

这个页面有240多k,几乎全都是javascript代码。有兴趣分析的兄弟姐妹们请点这里下载

其实其中大部分都是老生常谈的js代码了,不过我们可以一窥google的编码风格:尽可能压缩信息量,变量名能用一个字母的绝不用两个,函数名一概都是两个字母的,函数内的会车是没有的,缩进也是没有的。虽然代码没有特地加密,但是如此处理一番之后也就没什么可读性了。还好系统的关键字是不能缩水的,顺着xml控件的名字我们可以揪出来跟AJAX异步加载数据相关的几个关键函数:

function vb(){ var a = null ; if (r){ var b = fG ? " Microsoft.XMLHTTP " : " Msxml2.XMLHTTP " ; try {a = new ActiveXObject(b)} catch (c){q(c);alert( " 您需要启用活动脚本功能和activeX控件。 " )}} else {a = new XMLHttpRequest(); if ( ! a){;alert( " 此浏览器不支持XMLHttpRequest。 " )}} return a}
// emu注释构造XML控件并返回给调用者

function ot(a,b){; try {a.send(b)} catch (c){q(c); if (c.number ==- 2146697208 ){alert( " 请确保InternetExplorer的”语言”设置部分不是空白。 " )}}}
// emu注释执行发送数据操作a:XML控件b:要发送的数据

function Wf(a,b,c){Da( 3 );b = Ld(b);Hf(a,b,c)}
// emu注释a:XML控件b:访问的urlc:回调函数Da是验证参数长度的函数
//
Ld是一个url转换加工的函数,主要处理url自带的CGI参数和翻页的页数等

function Hf(a,b,c){Da( 3 );a.onreadystatechange = c;a.open( " GET " ,b, true );ot(a, null )}
// emu注释不发送数据直接请求资源a:XML控件b:访问的urlc:回调函数

function nt(a,b,c,d){Da( 4 );a.onreadystatechange = d;a.open( " POST " ,b, true );ot(a,c)}
// emu注释发送数据并请求资源a:XML控件b:访问的urlc:要发送的数据d:回调函数

基本上就这么多了,很失望吧,没有什么新鲜的东西。发送http请求之后它又怎么处理返回的xml的呢?事实上他没有处理。他所处理的仅仅是最基本responseText,而cgi则直接生成js脚本到客户端回调(用eval运行),或者生成文本信息。这就是为什么gmail可以轻松跨域几个浏览器了。

作为最受推崇的一个AJAX应用,却几乎没有用到xml。像这样用xml控件来收发文本信息后在页面上展现的技术,基本上就是现在AJAX最流行的应用方式了,不过这样也能叫AJAX吗?我宁可就叫它AJ,最多叫AJAH。

今天先到这,下回再过来分析另一个完全不同的AJAX应用吧。大家周末愉快!

function vb(){ var a = null ; if (r){ var b = fG ? " Microsoft.XMLHTTP " : " Msxml2.XMLHTTP " ; try {a = new ActiveXObject(b)} catch (c){q(c);alert( " 您需要启用活动脚本功能和activeX控件。 " )}} else {a = new XMLHttpRequest(); if ( ! a){;alert( " 此浏览器不支持XMLHttpRequest。 " )}} return a}
// emu注释构造XML控件并返回给调用者

function ot(a,b){; try {a.send(b)} catch (c){q(c); if (c.number ==- 2146697208 ){alert( " 请确保InternetExplorer的”语言”设置部分不是空白。 " )}}}
// emu注释执行发送数据操作a:XML控件b:要发送的数据

function Wf(a,b,c){Da( 3 );b = Ld(b);Hf(a,b,c)}
// emu注释a:XML控件b:访问的urlc:回调函数Da是验证参数长度的函数
//
Ld是一个url转换加工的函数,主要处理url自带的CGI参数和翻页的页数等

function Hf(a,b,c){Da( 3 );a.onreadystatechange = c;a.open( " GET " ,b, true );ot(a, null )}
// emu注释不发送数据直接请求资源a:XML控件b:访问的urlc:回调函数

function nt(a,b,c,d){Da( 4 );a.onreadystatechange = d;a.open( " POST " ,b, true );ot(a,c)}
// emu注释发送数据并请求资源a:XML控件b:访问的urlc:要发送的数据d:回调函数

基本上就这么多了,很失望吧,没有什么新鲜的东西。发送http请求之后它又怎么处理返回的xml的呢?事实上他没有处理。他所处理的仅仅是最基本responseText,而cgi则直接生成js脚本到客户端回调(用eval运行),或者生成文本信息。这就是为什么gmail可以轻松跨域几个浏览器了。

作为最受推崇的一个AJAX应用,却几乎没有用到xml。像这样用xml控件来收发文本信息后在页面上展现的技术,基本上就是现在AJAX最流行的应用方式了,不过这样也能叫AJAX吗?我宁可就叫它AJ,最多叫AJAH。

今天先到这,下回再过来分析另一个完全不同的AJAX应用吧。大家周末愉快!

<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="content-type">
<title>Gmail</title>
<link rel="alternate" type="application/atom+xml" title="Gmail Atom Feed" href="feed/atom" />
<script src="?view=page&name=browser&ver=c0d3d44c64799453"></script>
</head>
<noscript>
<font face=arial>
应启用 JavaScript,才能在标准视图中使用 Gmail。然而,JavaScript 似乎已被禁用,要么就是您的浏览器不支持 JavaScript。要使用标准视图,请更改您的浏览器选项以启用 JavaScript,然后<a href="">重试</a>。<p>要使用 Gmail 的基本 HTML 视图(不需要 JavaScript),<a href="?ui=html&zy=n">请单击此处</a>。</p>
</font>
</noscript>
<script>
<!--
var fs_time = (new Date()).getTime();
function wfs() {
try {
if (parent != window && parent.wfs) {
return false;
}
} catch(e) {
}
if (top.location.href.indexOf('nocheckbrowser') != -1) {
return true;
}
if (!is_browser_supported) {
top.location = '?ui=html&zy=j';
return false;
}
var testcookie = 'jscookietest=valid';
document.cookie = testcookie;
if (document.cookie.indexOf(testcookie) == -1) {
top.location = 'html/zh-CN/nocookies.html';
return false;
}
document.cookie = testcookie + ';expires=' + new Date(0).toGMTString();
var agt = navigator.userAgent.toLowerCase();
if (agt.indexOf('msie')!= -1 && document.all &&agt.indexOf('opera') == -1 && agt.indexOf('mac') == -1) {
eval("var control = (agt.indexOf('msie 5') != -1) ? 'Microsoft.XMLHTTP' : 'Msxml2.XMLHTTP';try {new ActiveXObject(control);} catch (e) {top.location = 'html/zh-CN/noactivex.html';}");
}
return true;
}
function lj() {
js.location.replace('?view=page&name=js&ver=d6079057e81abd3c');
}
if (wfs()) {
document.write("<frameset onload=lj() rows=\"100%,*\" border=0><frame name=main src=html/zh-CN/loading.html frameborder=0 noresize scrolling=no><frame name=js src=html/zh-CN/loading.html frameborder=0 noresize></frameset>");}
//-->
</script>
</html>

这是主框架网页兼浏览器检测页。如果浏览器通过了检测(支持javascript、cookie和xml控件)则在页面上写一段框架代码

要注意到的是google在这里耍了一个小花招,那个叫做main的框架页面里面看来没有多少东西,好东东都在那个叫js的框架里面呢。

我们接着把这个js框架拉出来看看:

整整1500多行的javascript代码!

这个页面有240多k,几乎全都是javascript代码。有兴趣分析的兄弟姐妹们请点这里下载

其实其中大部分都是老生常谈的js代码了,不过我们可以一窥google的编码风格:尽可能压缩信息量,变量名能用一个字母的绝不用两个,函数名一概都是两个字母的,函数内的会车是没有的,缩进也是没有的。虽然代码没有特地加密,但是如此处理一番之后也就没什么可读性了。还好系统的关键字是不能缩水的,顺着xml控件的名字我们可以揪出来跟AJAX异步加载数据相关的几个关键函数:

function vb(){ var a = null ; if (r){ var b = fG ? " Microsoft.XMLHTTP " : " Msxml2.XMLHTTP " ; try {a = new ActiveXObject(b)} catch (c){q(c);alert( " 您需要启用活动脚本功能和activeX控件。 " )}} else {a = new XMLHttpRequest(); if ( ! a){;alert( " 此浏览器不支持XMLHttpRequest。 " )}} return a}
// emu注释构造XML控件并返回给调用者

function ot(a,b){; try {a.send(b)} catch (c){q(c); if (c.number ==- 2146697208 ){alert( " 请确保InternetExplorer的”语言”设置部分不是空白。 " )}}}
// emu注释执行发送数据操作a:XML控件b:要发送的数据

function Wf(a,b,c){Da( 3 );b = Ld(b);Hf(a,b,c)}
// emu注释a:XML控件b:访问的urlc:回调函数Da是验证参数长度的函数
//
Ld是一个url转换加工的函数,主要处理url自带的CGI参数和翻页的页数等

function Hf(a,b,c){Da( 3 );a.onreadystatechange = c;a.open( " GET " ,b, true );ot(a, null )}
// emu注释不发送数据直接请求资源a:XML控件b:访问的urlc:回调函数

function nt(a,b,c,d){Da( 4 );a.onreadystatechange = d;a.open( " POST " ,b, true );ot(a,c)}
// emu注释发送数据并请求资源a:XML控件b:访问的urlc:要发送的数据d:回调函数

基本上就这么多了,很失望吧,没有什么新鲜的东西。发送http请求之后它又怎么处理返回的xml的呢?事实上他没有处理。他所处理的仅仅是最基本responseText,而cgi则直接生成js脚本到客户端回调(用eval运行),或者生成文本信息。这就是为什么gmail可以轻松跨域几个浏览器了。

作为最受推崇的一个AJAX应用,却几乎没有用到xml。像这样用xml控件来收发文本信息后在页面上展现的技术,基本上就是现在AJAX最流行的应用方式了,不过这样也能叫AJAX吗?我宁可就叫它AJ,最多叫AJAH。

今天先到这,下回再过来分析另一个完全不同的AJAX应用吧。大家周末愉快!

function vb(){ var a = null ; if (r){ var b = fG ? " Microsoft.XMLHTTP " : " Msxml2.XMLHTTP " ; try {a = new ActiveXObject(b)} catch (c){q(c);alert( " 您需要启用活动脚本功能和activeX控件。 " )}} else {a = new XMLHttpRequest(); if ( ! a){;alert( " 此浏览器不支持XMLHttpRequest。 " )}} return a}
// emu注释构造XML控件并返回给调用者

function ot(a,b){; try {a.send(b)} catch (c){q(c); if (c.number ==- 2146697208 ){alert( " 请确保InternetExplorer的”语言”设置部分不是空白。 " )}}}
// emu注释执行发送数据操作a:XML控件b:要发送的数据

function Wf(a,b,c){Da( 3 );b = Ld(b);Hf(a,b,c)}
// emu注释a:XML控件b:访问的urlc:回调函数Da是验证参数长度的函数
//
Ld是一个url转换加工的函数,主要处理url自带的CGI参数和翻页的页数等

function Hf(a,b,c){Da( 3 );a.onreadystatechange = c;a.open( " GET " ,b, true );ot(a, null )}
// emu注释不发送数据直接请求资源a:XML控件b:访问的urlc:回调函数

function nt(a,b,c,d){Da( 4 );a.onreadystatechange = d;a.open( " POST " ,b, true );ot(a,c)}
// emu注释发送数据并请求资源a:XML控件b:访问的urlc:要发送的数据d:回调函数

基本上就这么多了,很失望吧,没有什么新鲜的东西。发送http请求之后它又怎么处理返回的xml的呢?事实上他没有处理。他所处理的仅仅是最基本responseText,而cgi则直接生成js脚本到客户端回调(用eval运行),或者生成文本信息。这就是为什么gmail可以轻松跨域几个浏览器了。

作为最受推崇的一个AJAX应用,却几乎没有用到xml。像这样用xml控件来收发文本信息后在页面上展现的技术,基本上就是现在AJAX最流行的应用方式了,不过这样也能叫AJAX吗?我宁可就叫它AJ,最多叫AJAH。

今天先到这,下回再过来分析另一个完全不同的AJAX应用吧。大家周末愉快!

整整1500多行的javascript代码!

这个页面有240多k,几乎全都是javascript代码。有兴趣分析的兄弟姐妹们请点这里下载

其实其中大部分都是老生常谈的js代码了,不过我们可以一窥google的编码风格:尽可能压缩信息量,变量名能用一个字母的绝不用两个,函数名一概都是两个字母的,函数内的会车是没有的,缩进也是没有的。虽然代码没有特地加密,但是如此处理一番之后也就没什么可读性了。还好系统的关键字是不能缩水的,顺着xml控件的名字我们可以揪出来跟AJAX异步加载数据相关的几个关键函数:

function vb(){ var a = null ; if (r){ var b = fG ? " Microsoft.XMLHTTP " : " Msxml2.XMLHTTP " ; try {a = new ActiveXObject(b)} catch (c){q(c);alert( " 您需要启用活动脚本功能和activeX控件。 " )}} else {a = new XMLHttpRequest(); if (
(1)普通用户端(全平台) 音乐播放核心体验: 个性化首页:基于 “听歌历史 + 收藏偏好” 展示 “推荐歌单(每日 30 首)、新歌速递、相似曲风推荐”,支持按 “场景(通勤 / 学习 / 运动)” 切换推荐维度。 播放页功能:支持 “无损音质切换、倍速播放(0.5x-2.0x)、定时关闭、歌词逐句滚动”,提供 “沉浸式全屏模式”(隐藏冗余控件,突出歌词与专辑封面)。 多端同步:自动同步 “播放进度、收藏列表、歌单” 至所有登录设备(如手机暂停后,电脑端打开可继续播放)。 音乐发现与管理: 智能搜索:支持 “歌曲名 / 歌手 / 歌词片段” 搜索,提供 “模糊匹配(如输入‘晴天’联想‘周杰伦 - 晴天’)、热门搜索词推荐”,结果按 “热度 / 匹配度” 排序。 歌单管理:创建 “公开 / 私有 / 加密” 歌单,支持 “批量添加歌曲、拖拽排序、一键分享到社交平台”,系统自动生成 “歌单封面(基于歌曲风格配色)”。 音乐分类浏览:按 “曲风(流行 / 摇滚 / 古典)、语言(国语 / 英语 / 日语)、年代(80 后经典 / 2023 新歌)” 分层浏览,每个分类页展示 “TOP50 榜单”。 社交互动功能: 动态广场:查看 “关注的用户 / 音乐人发布的动态(如‘分享新歌感受’)、好友正在听的歌曲”,支持 “点赞 / 评论 / 转发”,可直接点击动态中的歌曲播放。 听歌排行:个人页展示 “本周听歌 TOP10、累计听歌时长”,平台定期生成 “全球 / 好友榜”(如 “好友中你本周听歌时长排名第 3”)。 音乐圈:加入 “特定曲风圈子(如‘古典音乐爱好者’)”,参与 “话题讨论(如‘你心中最经典的钢琴曲’)、线上歌单共创”。 (2)音乐人端(创作者中心) 作品管理: 音乐上传:支持 “无损音频(FLAC/WAV)+ 歌词文件(LRC)+ 专辑封面” 上传,填写 “歌曲信息
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值