Ajax开发的陷阱与prototype.js工具包应用
1. Ajax应用的潜在问题
1.1 错误处理
如果Ajax应用在某些条件下崩溃,至少应该向用户报告明显的错误,如无法创建
XMLHTTPRequest
对象实例。若应用过于复杂,无法自动恢复到非Ajax模式,可将用户重定向到非Ajax版本的应用。
可以使用HTML页面中的
<noscript> … </noscript>
标签检测JavaScript是否可用。示例代码如下:
<noscript>
JavaScript is not available in this browser. <br />
Please go <a href="otherplace.htm">HERE</a> for
the HTML-only version.<br />
</noscript>
1.2 搜索引擎爬虫问题
搜索引擎通过爬虫程序收集网站信息。对于高度动态的网站,爬虫可能无法访问通过动态方式加载的内容,从而无法对其进行索引。使用Ajax可能会加剧这个问题,因为它倾向于在更少的页面中提供更多内容。
为解决此问题,应确保爬虫能够索引网站上所有相关内容的静态版本。可以提供一个超文本链接的网站地图,因为爬虫会跟随页面中嵌入的链接。
1.3 页面元素交互提示
如果设计不当,用户可能不清楚页面上哪些元素可以点击或交互。可以在整个应用中使用一致的样式来显示哪些页面元素会引发服务器请求或其他动态活动,类似于HTML页面中超文本链接的样式与普通文本不同。
还可以通过Tooltip样式的弹出窗口提供有关活动元素的说明和信息,特别是当点击活动链接会对应用状态产生重大影响时。
1.4 不适合使用Ajax的场景
虽然Ajax可以显著改善Web界面,但在很多情况下,使用Ajax会降低用户体验。例如,基于页面的界面隐喻对于某些网站的内容和风格已经足够,甚至更合适。文本类网站将主题方便地拆分为章节式页面,通过智能设计的超链接可能与添加Ajax功能一样有益。小型网站可能难以从Ajax界面中获得足够的好处来平衡额外代码和复杂性带来的成本。
1.5 安全问题
Ajax本身似乎不会带来设计Web应用时不存在的安全问题,但Ajax增强的应用往往包含更多客户端代码。由于客户端代码内容可被任何用户轻松查看,因此不应在其中透露敏感信息,包括用户名、密码和业务逻辑。应让服务器端脚本负责处理数据库连接等问题,并在服务器上验证数据后再进行重要处理。
1.6 跨平台测试
不同浏览器在实现JavaScript时表现不同,如Microsoft和非Microsoft浏览器在生成
XMLHTTPRequest
对象实例方面存在重大差异,DOM处理和CSS实现也有许多细微差别。因此,测试新应用在各种浏览器上的兼容性非常重要,尤其是在面对Ajax应用的复杂性时。应尽可能在不同平台和浏览器上测试应用。
1.7 编程陷阱
- 浏览器缓存GET请求 :重复向同一URL发送GET请求时,响应可能来自浏览器缓存而非服务器,在Internet Explorer中此问题尤为明显。可以通过在请求的URL中添加随机元素来解决,如添加随机数或基于时间的数字。示例代码如下:
var url = "serverscript.php"+"?rand="+new Date().getTime();
-
权限拒绝错误
:收到“Permission Denied”错误通常意味着违反了阻止
XMLHTTPRequest对象进行跨域请求的安全措施。调用必须针对与调用脚本位于同一域的服务器程序,且要确保域名的书写方式完全一致。 - 内容转义 :在构造GET或POST请求的查询时,要对可能包含空格或其他非文本字符的变量进行转义。示例代码如下:
http.open("GET", url + escape(idValue) + "&rand=" + myRandom, true);
2. prototype.js工具包介绍
2.1 引入prototype.js
prototype.js是一个流行的JavaScript库,包含一系列用于开发跨浏览器JavaScript例程的有用函数,尤其对Ajax提供了特定支持。可以从http://www.prototypejs.org/ 下载最新版本,在编写本文时,其版本为1.6.0。
在Web应用中引入该库很简单,只需在HTML文档的
<head>
部分添加以下代码:
<script src="prototype.js" Language="JavaScript" type="text/javascript"></script>
2.2 prototype.js的常用函数
-
$()函数
:是
getElementById()DOM方法的快捷方式。示例代码如下:
// 普通方式
var mydata = document.getElementById('someElementID');
// 使用$()函数
var mydata = $('someElementID');
$()
函数还可以接受多个元素ID作为参数,并返回一个包含相关元素值的数组。示例代码如下:
mydataArray = $('id1','id2','id3');
在这个例子中:
-
mydataArray[0]
包含ID为
id1
的元素的值。
-
mydataArray[1]
包含ID为
id2
的元素的值。
-
mydataArray[2]
包含ID为
id3
的元素的值。
- $F()函数 :当传入表单输入元素或其ID作为参数时,返回该表单输入字段的值。示例代码如下:
<input type="text" id="input1" name="input1">
<select id="input2" name="input2">
<option value="0">Option A</option>
<option value="1">Option B</option>
<option value="2">Option C</option>
</select>
// 返回文本框的值
$F('input1');
// 返回下拉框当前选中选项的值
$F('input2');
-
Form对象
:prototype.js定义了一个Form对象,有几个简化HTML表单操作的有用方法。
-
getElements()方法:返回表单输入字段的数组。示例代码如下:
-
inputs = Form.getElements('thisform');
- `serialize()`方法:将输入名称和值格式化为与URL兼容的列表。示例代码如下:
inputlist = Form.serialize('thisform');
- `Form.disable('thisform')`和`Form.enable('thisform')`分别用于禁用和启用表单。
- Try.these()函数 :提供了一种方便的方式来封装异常处理方法,以提供跨浏览器的解决方案。示例代码如下:
return Try.these(
function() {return new ActiveXObject('Msxml2.XMLHTTP')},
function() {return new ActiveXObject('Microsoft.XMLHTTP')},
function() {return new XMLHttpRequest()}
)
2.3 封装XMLHTTPRequest的Ajax对象
2.3.1 Ajax.Request
Ajax.Request
处理创建
XMLHTTPRequest
对象实例并发送正确格式请求的细节。调用方式如下:
var myAjax = new Ajax.Request( url, {method: 'post', parameters: mydata, onComplete: responsefunction} );
其中,
url
定义要调用的服务器资源的位置,
method
可以是
post
或
get
,
mydata
是包含请求参数的序列化字符串,
responsefunction
是处理服务器响应的回调函数。
第二个参数使用JSON(JavaScript Object Notation)表示法构建,由一系列参数:值对组成。
onComplete
参数对应
XMLHTTPRequest
的
readyState
属性值为4(完成)的情况,还可以使用
onLoading
、
onLoaded
或
onInteractive
指定在之前的阶段执行回调函数。还有其他可选参数,如
asynchronous:false
表示同步进行服务器调用,默认值为
true
。
2.3.2 Ajax.Updater
当需要用返回的数据更新页面元素时,
Ajax.Updater
类可以简化任务。只需指定要更新的元素:
var myAjax = new Ajax.Updater(elementID, url, options);
示例代码如下:
<script>
function updateDIV(mydiv)
{
var url = 'http://example.com/serverscript.php';
var params = 'param1=value1¶m2=value2';
var myAjax = new Ajax.Updater(
mydiv,
url,
{method: 'get', parameters: params}
);
}
</script>
<input type="button" value="Go" onclick="updateDIV(targetDiv)">
<div id="targetDiv"></div>
还可以添加
evalscripts:true
选项,使服务器返回的任何JavaScript代码都能被执行。
2.3.3 Ajax.PeriodicalUpdater
Ajax.PeriodicalUpdater
类可用于重复创建
Ajax.Updater
实例,以在一定时间间隔后更新页面元素。它在股票行情显示器或RSS阅读器等应用中很有用。
Ajax.PeriodicalUpdater
在
Ajax.Updater
选项的基础上增加了两个参数:
-
frequency
:连续更新之间的延迟时间(秒),默认值为2秒。
-
decay
:如果服务器返回未更改的数据,后续延迟增加的乘数,默认值为1,即延迟保持不变。
示例代码如下:
var myAjax = new Ajax.PeriodicalUpdater(elementID, url, {frequency: 3.0, decay: 2.0});
2.4 示例项目:股票价格阅读器
2.4.1 服务器端脚本
使用
rand.php
脚本模拟不断变化的股票价格:
<?php
srand ((double) microtime( )*1000000);
$price = 50 + rand(0,5000)/100;
echo "$price";
?>
2.4.2 HTML页面
构建一个简单的HTML页面来显示当前股票价格:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<script src="prototype.js" Language="JavaScript" type="text/javascript"></script>
<title>Stock Reader powered by Prototype.js</title>
</head>
<body>
<h2>Stock Reader</h2>
<h4>Powered by Prototype.js</h4>
<p>Current Stock Price:</p>
<div id="price"></div>
</body>
</html>
2.4.3 实现Ajax.PeriodicalUpdater
将
Ajax.PeriodicalUpdater
类附加到文档主体元素的
onLoad
事件处理程序中:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<script src="prototype.js" Language="JavaScript" type="text/javascript"></script>
<script>
function checkprice()
{
var myAjax = new Ajax.PeriodicalUpdater('price', 'rand.php', {method: 'post', frequency: 3.0, decay: 1});
}
</script>
<title>Stock Reader powered by Prototype.js</title>
</head>
<body onLoad="checkprice()">
<h2>Stock Reader</h2>
<h4>Powered by Prototype.js</h4>
<p>Current Stock Price:</p>
<div id="price"></div>
</body>
</html>
通过使用prototype.js,应用的代码变得非常简单,只需定义一个单行函数
checkprice()
来实例化重复的Ajax调用,并从主体元素的
onLoad
事件处理程序中调用该函数。
综上所述,在使用Ajax开发时,需要注意各种潜在问题,同时可以利用prototype.js工具包来简化开发过程,提高开发效率。
下面是一个简单的mermaid流程图,展示了
Ajax.PeriodicalUpdater
的工作流程:
graph TD
A[开始] --> B[创建Ajax.PeriodicalUpdater实例]
B --> C{设定时间间隔}
C --> D[发送请求]
D --> E{服务器返回数据}
E -- 数据变化 --> F[更新页面元素]
E -- 数据未变化 --> G{根据decay调整时间间隔}
G --> C
F --> C
在开发过程中,还可以通过以下表格总结不同函数和对象的功能:
| 函数/对象 | 功能 |
| — | — |
| $() | 简化获取元素值的操作 |
| $F() | 获取表单输入字段的值 |
| Form对象 | 简化HTML表单操作 |
| Try.these() | 封装异常处理方法 |
| Ajax.Request | 处理请求发送 |
| Ajax.Updater | 更新页面元素 |
| Ajax.PeriodicalUpdater | 定时更新页面元素 |
3. 总结与建议
3.1 开发要点回顾
在使用Ajax进行开发时,需要注意以下几个关键要点:
1.
错误处理
:确保在Ajax应用崩溃时能向用户报告明显错误,复杂应用可考虑重定向到非Ajax版本。
2.
搜索引擎友好
:为搜索引擎爬虫提供静态版本内容和超文本链接的网站地图。
3.
用户交互提示
:使用一致样式和Tooltip弹出窗口明确页面活动元素。
4.
适用场景判断
:评估是否适合使用Ajax,避免在不适合的场景增加复杂度。
5.
安全问题
:不在客户端代码中透露敏感信息,让服务器端处理关键业务逻辑。
6.
跨平台测试
:在多种浏览器和平台上测试应用,确保兼容性。
7.
编程陷阱处理
:处理浏览器缓存、权限拒绝和内容转义等问题。
3.2 prototype.js工具包优势
prototype.js工具包为Ajax开发提供了诸多便利,其主要优势如下:
-
简化代码
:通过快捷函数和对象封装,减少了开发过程中的代码量,提高了代码的可读性和可维护性。
-
跨浏览器支持
:提供了跨浏览器的解决方案,如
Try.these()
函数处理不同浏览器的
XMLHTTPRequest
对象创建。
-
表单处理
:
Form
对象的方法简化了HTML表单的操作,如序列化表单数据。
-
请求处理
:
Ajax
对象的不同类封装了请求发送、响应处理和页面更新等功能,使开发人员无需关注底层细节。
3.3 开发建议
- 谨慎使用Ajax :在决定是否使用Ajax时,要充分考虑应用的实际需求和场景,避免过度使用导致用户体验下降。
- 遵循最佳实践 :在编写代码时,遵循良好的编程习惯,如注释代码、验证数据和使用合适的命名规范。
- 持续测试 :不断在不同环境中测试应用,及时发现并解决兼容性和性能问题。
- 利用工具包 :合理利用prototype.js等工具包,提高开发效率和代码质量。
4. 常见问题解答
4.1 为什么我的Ajax请求总是返回缓存数据?
这可能是因为浏览器缓存了之前的请求响应。可以通过在请求的URL中添加随机元素来解决,例如:
var url = "serverscript.php"+"?rand="+new Date().getTime();
4.2 我收到了“Permission Denied”错误,该怎么办?
这个错误通常意味着你违反了跨域请求的安全限制。确保你的请求是针对与调用脚本位于同一域的服务器程序,并且域名的书写方式完全一致。
4.3 如何在prototype.js中处理表单数据?
可以使用
Form
对象的方法来处理表单数据。例如,使用
getElements()
方法获取表单输入字段的数组,使用
serialize()
方法将表单数据格式化为URL兼容的字符串:
// 获取表单输入字段数组
var inputs = Form.getElements('thisform');
// 序列化表单数据
var inputlist = Form.serialize('thisform');
4.4 如何定时更新页面元素?
可以使用
Ajax.PeriodicalUpdater
类来定时更新页面元素。以下是一个示例:
var myAjax = new Ajax.PeriodicalUpdater('elementID', 'url', {frequency: 3.0, decay: 1});
5. 总结
通过本文的介绍,我们了解了Ajax开发中可能遇到的各种问题以及如何使用prototype.js工具包来简化开发过程。在实际开发中,要充分考虑应用的需求和场景,合理使用Ajax技术,并遵循最佳实践,以提高开发效率和用户体验。
以下是一个总结表格,展示了Ajax开发的关键要点和prototype.js的主要功能:
| 类别 | 要点 | 说明 |
| — | — | — |
| Ajax开发要点 | 错误处理 | 向用户报告错误,复杂应用可重定向 |
| | 搜索引擎友好 | 提供静态内容和网站地图 |
| | 用户交互提示 | 使用一致样式和Tooltip |
| | 适用场景判断 | 避免过度使用 |
| | 安全问题 | 保护敏感信息 |
| | 跨平台测试 | 在多种环境中测试 |
| | 编程陷阱处理 | 处理缓存、权限和转义问题 |
| prototype.js功能 | 快捷函数 | $()、$F()简化操作 |
| | Form对象 | 简化表单处理 |
| | Try.these() | 跨浏览器异常处理 |
| | Ajax对象 | 封装请求和页面更新功能 |
下面是一个mermaid流程图,展示了使用prototype.js开发Ajax应用的基本流程:
graph TD
A[引入prototype.js] --> B[定义页面元素]
B --> C[处理表单数据]
C --> D[发送请求]
D --> E{服务器响应}
E -- 成功 --> F[更新页面元素]
E -- 失败 --> G[处理错误]
F --> H[定时更新(可选)]
G --> D
希望本文能帮助你更好地理解Ajax开发和prototype.js工具包的使用,在实际项目中取得更好的效果。
超级会员免费看
2

被折叠的 条评论
为什么被折叠?



