计算机教程

开发保留标准浏览器功能的AJAX应用程序(1)

6 7月 , 2019  

作者:Mark Schiefelbein

Ajax应用程序由于其丰富的功能、交互性以及快速的响应能力而得到人们的普遍赞许。它可以使用XMLHttpRequest对象动态地加载数据,而不是加载新的页面。在它大肆进行宣传以及许多人兴奋的同时,有评论指出,Ajax应用程序丢失了浏览器的一些重要功能,包括对后退前进按钮的支持。
本文将首先阐明为什么在Ajax应用程序中除非显式地构建后退/前进按钮以及其它浏览器功能,否则它们将无法运行的原因。然后,我们将简要介绍开发人员如何解决这些问题。最后,我们将看到有关Backbase
Ajax引擎如何支持后退/前进按钮以及其它标准浏览器功能的详细情况。
Ajax应用程序是否需要后退按钮?
Ajax承诺,可以让开发人员完全基于标准的Web浏览器技术通常是指DHTML)创建在视觉上吸引人的、高度交互式的Web应用程序。
以前开发人员不得不在功能丰富具有高度交互性的、吸引人的用户界面)和易于到达不需要进行客户端安装就可以工作在所有Web浏览器下的前端)二者之中作出选择。而Ajax应用程序应该能够产生既“功能丰富”又“易于到达”的前端。
但是一个界面怎样才算是“功能丰富”的,而一个应用程序又怎样才是“易于到达”的呢?
很难精确地定义“功能丰富”的含义,但是却很容易直觉地认识到:当您看到一个界面时,您就会知道它是不是功能丰富的。象Microsoft
Office之类的桌面应用程序就是功能丰富的。功能丰富的界面使用诸如选项卡和上下文菜单这样的高级UI控件。这样的界面提供一些高级交互方法。例如,拖放、对关注的UI元素进行高亮显示等。传统的浏览器应用程序是功能不丰富的。它们仅限于诸如表单之类的简单控件,交互主要是由到新页面的单击链接组成。我们只要看看微软的电子邮件客户端就可以看出功能丰富和功能不丰富的区别:Outlook是功能丰富的,而Hotmail就是功能不丰富的。
Ajax应用程序已经由于功能丰富而得到人们的普遍赞许。Google的Gmail就是其中最具代表性的例子。Google所开发的其它Ajax应用程序Google
Suggest、 Google
Map)、微软即将推出的名为“Kahuna”的Web邮件客户端以及Backbase RSS
Reader都包含了一些高级控件和交互模块。
通过前面的讨论,可以说Ajax应用程序很明显满足“功能丰富”的标准。那么它是不是“易于到达”的呢?
首先,最基本的是,只有界面在Web浏览器中运行的应用程序才是“易于到达”的。Ajax应用程序是基于浏览器标准的,因此可以通过Web浏览器来访问。
但是,仅仅可以通过Web浏览器访问还不够。终端用户希望在使用Web应用程序时所面对的是特定的交互方式。应用程序需要遵从传统的Web交互方式,并提供以下的可用功能:

 

  • 后退和前进按钮可以正常工作,以便终端用户可以导航到历史记录页面。
  • 用户应该可以创建书签。
  • 支持深链接,以保证终端用户可以将这个页面通过电子邮件发送给朋友和同事。
  • 刷新按钮可以正常工作,以便刷新当前的状态而不是重新初始化应用程序。
  • 开发人员可以使用“查看源文件”看到源代码。
  • 终端用户可以使用“查找”对页面进行搜索。
  • 搜索引擎可以为页面做索引并创建到搜索项的深链接。

摘要

以前讨论的大多数Ajax应用程序的确打破了标准的Web交互方式。在下一节中,我们将讨论为什么许多Ajax应用程序会这么做。

为什么Ajax应用程序常常会使后退按钮无法正常工作?

我们所说的Web基于以下三个原则:

AJAX
应用因为它们的表现力的丰富、更加互动和更加迅速的响应得到了赞扬声;这些优点都是通过使用XMLHttpRequest对象来动态的载入数据而获得的,
而不是重新载入新的页面。在大量的宣传和刺激中,却有一些批评的声音指出,AJAX应用破坏了一些重要的浏览器特性,这其中包括对前进/后退按钮的支持。

  • 使用 (D)HTML来定义界面
  • 使用HTTP实现客户端与服务器间的通讯
  • 使用URI进行寻址

本文首先解释了为什么除非明确的将那些功能做进AJAX应用,否则前进/后退按钮和其他一些浏览器功能不能正常工作。然后简单的列出开发者如何解决上述问题,最后我们将详细的看一看Backbase
AJAX引擎是如何提供对前进/后退按钮和其他一些浏览器功能的支持的。

Ajax编程突破了由以上原则所带来的种种限制,使得界面功能更加丰富。Ajax广泛使用了JavaScript“J”)以创建功能丰富的UI组件和交互性。Ajax还引入了异步的XML通信“A”和“X”),也就是使用XMLHttpRequest对象导入新的数据和表示逻辑而不必刷新页面。然而,目前的Ajax模型并没有解决如何处理URI的问题。
Ajax应用程序对(D)HTML和HTTP的使用方式做了改变,而这种改变带来的直接结果就是后退按钮和Web的基本交互方式的其它元素无法正常工作了。在本节的其余部分,我将说明如何通过以Ajax的方式处理URI来解决上述问题。首先我们来看看在传统的Web应用程序中URI是如何与用户交互相关联的。
从技术方面来说,用户交互是指用户界面状态的一次更改。状态改变由终端用户发起。浏览器客户端通过向服务器发出页面请求来处理状态更改REST法则)。服务器将发送新的页面和新的URI到客户端以生成新的界面状态。
简单地说,每个用户交互都是通过会导致如下结果的服务器往返来处理的:

AJAX应用需要一个后退按钮吗?

  • 生成新的页面
  • 生成新的URI

AJAX许诺允许开发者仅仅使用标准的浏览器技术开发有更好用户体验的和高度互交的WEB应用,这种技术常常是指DHTML。

这些Web功能之所以能够被使用,是因为浏览器在它的历史记录堆栈中记录了连续的URI,并在地址栏中向终端用户显示当前URI,用户可以通过地址栏复制URI,并将其发送给朋友。当用户单击后退按钮或者向浏览器的地址栏中粘贴一个来自于电子邮件的URI时,就会触发一次到服务器的往返。因为服务器负责状态管理,所以它就可以生成相应的页面。
Ajax应用程序与传统的Web应用程序之间的主要区别在,Ajax应用程序可以处理用户的交互而无需页面重新加载。例如,通过XMLHttpRequest对象从服务器载入数据,或者使用JavaScript来处理拖放客户端。
在上面的两个例子中,状态改变了,但是却没有生成新的URI。因此,单击后退按钮或刷新按钮会产生意外的结果,在地址栏中也不会有深链接的URI。
为了提供传统的Web可用功能,Ajax应用程序需要以类似于服务器处理传统的Web应用程序的方式来处理URI客户端。Ajax应用程序需要实现以下功能:

以前,开发者常常不得不在richreach之间做出选择;前者是指具有高度互交性的交互式的用户接口,后者是指一个运行在所有WEB浏览器上的、不用额外的安装机制的前台终端。AJAX应用将使得前台终端既“rich”又“reach”。

  • 当客户端状态发生改变时,生成一个URI,并将其发送到浏览器
  • 当浏览器请求新的URI时可以重新创建状态。

但是到底什么是真正的一个界面“rich”的含义呢?而什么又是一个应用“reach”的含义呢?

实现以上功能后,浏览器的历史记录就可以正常工作,浏览器的地址栏就可以显示URI,当然,您也就可以将它发送给朋友了。
这里还有另外一个难点,那就是如何确定Ajax引擎什么时候需要实现以上功能例如,哪一次状态改变需要创建新的URI)。在传统的模式中,每一次页面刷新都对应着一次URI更新。而在Ajax模式中,每一个客户端事件都将新的URI添加到浏览器堆栈中。交互设计者和开发人员将不得不做出决定:哪一次状态改变是有意义的。只对有意义的状态改变才需要生成URI。
下面我们对提供Web可用功能的Ajax应用程序在客户端需要实现的功能做一下总结:

“rich”
的概念不容易定义,但是容易被直观的感受。如果你看到一个“rich”界面,你将明白什么是“rich”界面。桌面应用像微软的Office就是一个
“rich”的界面。一个“rich”的界面使用先进的UI控制技术,如Tabs和上下文菜单。它们提供前进的互交手段,像当它们获得焦点的时候,UI元
素的drag-and-drop和highlighting。传统的浏览器应用不是“rich”的。它们被限制在一些简单的控制器里,像Form,而交互
只是简单的依靠点击链接到一个新的页面。看看微软的email客户端就能看出其中的差别:Outlook是“rich”的,而hotmail则不是。

  • 创建历史记录
    • 保存有意义的状态
    • 生成相应的URI
    • 将这个URI添加到浏览器的堆栈中
  • 恢复历史记录
    • 检测URI的改变
    • 通过URI重新创建状态

AJAX应用因为它们的富有的表现力而得到表扬,Google的Gmail就是一个经常提及的例子。其他的Google所做的AJAX应用,如Google
Suggest和Google Map。微软即将发布的Web
mail客户端,代号为:“Kahuna”,或者Backbase RSS
Reader也包含了高级的控制器和互交的模型。看一看Dan Grossman的列表:Top 10
Ajax Applications,那里是一些激动人心的关于“rich”界面的列表。

在Ajax中支持后退按钮的基本设计思想
在这一节中,我们将讨论在Ajax应用程序中支持后退按钮所需的基本步骤,并给出说明所需步骤的简单示例代码。
简单示例程序如图1所示,在界面中将有一个选择框,它有两个值:“Year
1”和“Year
2”。对于这个程序,我们将在选择框值发生改变时跟踪历史记录。这意味着用户可以首先选择“Year
2”然后单击后退按钮后退到先前的选择。

因此我可以得出结论,AJAX应用很明白的满足“rich”的概念。但是它是否满足“reach”呢?

图片 1
图1.带有选择框的简单示例程序

在AJAX应用的绝大多数基本表单里,如果界面运行在一个WEB浏览器里,那么这个应用是“reach”的。AJAX应用是基于标准的浏览器的,因此能够被一个浏览器所访问。

示例程序最初是一个带有JavaScript
getter和setter用于选择框值)的简单HTML表单:

但是,仅仅被浏览器所理解还是不够的。Jakob Nielson在他的文章Flash: 99%
Bad里,指出Flash:“破坏了WEB的基本的交互风格”。在使用WEB应用的时候,终端用户期望一个确定的交互风格。应用需要提供传统的WEB交互风格,并且提供如下的可用性特性:

  






。必须提供“后退/前进”按钮,用户能够浏览网页历史纪录

我们将首先实现第一个要求:创建状态的历史记录。正如我们前面所提到的,这个要求包含以下三个步骤:

。用户能够使用书签

  • 创建历史记录
    • 保存有意义的状态
    • 生成相应的URI
    • 将这个URI添加到浏览器的堆栈中

。必须提供Deep links,以便用户能够将其通过email发送给朋友或同事

我们希望能够保存选择框的每一次更改。因此我们将创建新的包含选择框状态信息的URI。
为了遵循Internet标准,我们将使用URI的碎片标识符部分。按照IETF RFC
3986的规定,“……作为客户端间接引用的主要形式,碎片标识符在信息检索系统中起着特殊的作用,〈……〉碎片标识符在解除引用之前与URI的其余部分是分离的,因此,碎片本身中的标识信息只被用户代理所废弃,而不考虑URI方案……”。

。必须提供“刷新”按钮,用来刷新当前状态,而不是通过重新初始化应用来获得

使用碎片标识符,我们可以创建一个“Ajax-URI”,其中的客户端部分和服务器端部分使用“#”隔开。
JavaScript提供了window.location()函数,以便通过URI更新浏览器的历史记录和地址。此外,我们可以使用window.location.hash()直接访问碎片标识符。

。开发人员可以通过使用“view source”来查看源代码

http://www.bkjia.com/Javascript/592058.htmlwww.bkjia.comtruehttp://www.bkjia.com/Javascript/592058.htmlTechArticleAjax应用程序由于其丰富的功能、交互性以及快速的响应能力而得到人们的普遍赞许。它可以使用XMLHttpRequest对象动态地加载数据,而不是加

。终端用户能够使用“find”来搜索页面

。搜索引擎能够对网页编索引,能够产生一个Deep link来搜索它们

看一看10个顶级的AJAX应用,表明大多数的当前AJAX应用的确破坏了WEB的基本交互风格。在接下来的部分里,我们将看一看为什么很多的AJAX应用会这样。

 

为什么AJAX应用经常性的破坏了后退按钮?

我们今天所知道的WEB牢固的建立在以下三个原则的基础上:

。使用(D)HTML建立的界面

。使用HTTP为客户/服务器通讯

。使用URIs寻址

上面的原则决定了我们所获取的WEB应用有一定的局限性,而AJAX应用正是通过冲破这种局限性的限制而使得界面变得更加丰富。正像我以前的文章:A
Backbase Ajax Front-end for J2EE Applications所
解释的。AJAX引入了广泛使用的Javascript(AJAX中的J)来创建丰富的UI界面控制器和交互。AJAX也引入了异步的XML通讯
(AJAX中的A和X),这是通过引入XMLHttpRequest对象来载入新的数据和表现层逻辑,而没有页面刷新。然而,当前的AJAX模型,不能够
定位如何处理URIs。

作为改变使用(D)HTML和HTTP的一个直接后果,AJAX应用破坏了作为WEB基本交互风格的后退按钮和其他的元素。在本文余下的部分,我将解释如何在AJAX方式下通过处理URIs来修补这种破坏。我首先将说一说为什么URIs会和传统的WEB应用的交互有关系。

用户交互用术语来说就是用户界面的状态发生了改变。终端用户发起了状态改变,浏览器客户端通过发送页面请求到服务器的方式来处理状态变化(REST原则),服务器通过发送一个新的页面和新的URIs到客户端来产生一个新的界面状态。

简而言之,每一个用户交互是这样别处理的,通过服务器的循环产生如下的结果:

。产生一个新的页面

。产生一个新的URI


为浏览器记录了连续的URIs到它的历史堆栈里,并且将当前的URI显示在地址栏里,WEB的可用性特性就被激活。在地址栏里,用户可以拷贝URI,并且
可以把它发送给朋友。当用户点击返回按钮或从email里粘贴一个URI到地址栏里,一个到服务器的循环就被触发。由于服务器负责状态管理,那么服务器就
能产生相应的页面。

AJAX应用和传统的WEB应用的最大的不同在于AJAX应用能够不通过页面的重载而处理用户的交互。通过XMLHttpRequest对象从服务器载入数据就是一个例子。使用Javascript处理客户端drag-and-drop是另外的一个例子。

在上面的两个例子中,状态的变化不是通过产生一个新的URI得到的。因此,点击后退按钮或者刷新按钮不能得到想要的效果,并且在地址栏里没有deep-link的URI。

为了提供传统的WEB可用性特性,AJAX应用需要像传统的WEB应用一样来处理URIs客户端。因此AJAX应用需要做如下的事:

。当一个客户端状态变化时,产生一个URI,并且发送到客户端

。当一个新的URI被客户端请求时,保存状态

做到了上面的两点,浏览器的历史纪录将会工作,浏览器的地址栏将显示一个能发送给朋友的URI。


外一个困难是决定什么时候AJAX引擎应该做上面的那两件事(例如,什么样的状态变化将导致产生一个新的URI)。在传统的模式中,每一个页面刷新都导致
一个URI的更新。在AJAX模式中,每一个客户端事件都可能产生一个URI到浏览器堆栈。交互设计师和开发者将决定什么样的状态变化是有意义的。因而只
对那些有意义的状态变化产生新的URI。

我将总结AJAX应用需要提供WEB可用性特性的客户端需求:

1.      
产生历史纪录

a.      
保存有意义的状态

b.      
产生相应的URI

c.      
将URI推到浏览器堆栈

2.      
恢复历史纪录

a.      
探测URI变化

b.      
维护从URI得到的状态

 

在AJAX中支持后退按钮的基本设计

在这个部分,我们将讨论在AJAX应用中支持后退按钮的基本步骤。我将引入一些简单的代码来展示必需的步骤。关于如何实现跨浏览器兼容的后退按钮的支持的更为完整的方法已经实现了。在我喜欢的MikeStenhouse(Content
with Style)和Brad Neuberg (OnJava)所写的两篇文章里有描述。

如图1所示,我的简单示例应用上有一个选择框,里面有两个选择项:Year
1和Year
2。因为本文的主旨,当选择框的值发生变化时,我们将纪录它的历史纪录。这意味着用户如果首先选择Year
2的话,然后点击后退按钮将退回到前面的选择。

图片 2

                  图1:一个只有一个选择框的简单示例

 

这个示例应用的开始部分只是一些简单的HTML代码,里面有一些为选择框的值所作的getter和setter方法的JS代码:

<html>

 

<head>

<script language="JavaScript" type="text/JavaScript">

function reportOptionValue()

{

 var myForm = document.make_history;

 var mySelect = myForm.change_year;

 return mySelect.options[mySelect.selectedIndex].value;

}

 

function setOptionValue(value)

{

 var myForm = document.make_history;

 var mySelect = myForm.change_year;

 mySelect.options[value-1].selected = true;

}

</script>

</head>

 

<body>

<form name=make_history>

 <select name=change_year>

    <option value="year_1">Year 1</option>

    <option value="year_2">Year 2</option>

 </select>

</form>

</body>

 

</html>

 

我们首先是处理第一个需求:产生状态的历史纪录。就像前面所提到的,这个需求包括下面的三个部分:

1. 
生历史纪录

a.保存有意义的状态

b.产生相应的URI

c.将URI推到浏览器堆栈

我希望保存的状态是每一次选择框的值的改变,因此我需要产生一个新的包含选择框的状态信息的URI。

为了保持对标准的因特网的适应,我使用URI的片断标识符,这在IETF RFC
3986里有表述。“…片断标识符作为客户端原始表单的间接引用,在信息恢复系统中担当了一个特殊的角色。<…>片断标识符是URI废弃的那部分,不管URI的模式,片断内部的识别信息被用户代理废弃了…”

使用片断标识符,我能产生一个“AJAX-URI”,由客户端和服务器段组成,使用“#”符号分割。

JavaScript提供window.location()方法来更新浏览器历史和定位URI。另外,你能通过window.location.hash()``直接访问片断标识符。

下面的代码片断,你将看到我通过处理选择框的onchange事件来更新历史纪录和使用“AJAX-URI”来更新地址栏的方法来扩展代码。

<html>

 

<head>

<script language="JavaScript" type="text/JavaScript">

function makeHistory(newHash)

{

 window.location.hash = newHash;

}

 

function reportOptionValue()

{

 var myForm = document.make_history;

 var mySelect = myForm.change_year;

 return mySelect.options[mySelect.selectedIndex].value;

}

 

function setOptionValue(value)

{

 var myForm = document.make_history;

 var mySelect = myForm.change_year;

 mySelect.options[value-1].selected = true;

}

</script>

</head>

 

<body>

<form name=make_history>

 <select name=change_year 

    onchange=

      "return makeHistory(reportOptionValue())">

    <option value="year_1">Year 1</option>

    <option value="year_2">Year 2</option>

 </select>

</form>

</body>

 

</html>


相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图