ajax服务器端
现代Web应用程序都基于各种与Ajax相关的概念。 Ajax技术的使用导致网页上交互式或动态界面的增加。 Ajax的革命始于Web应用程序可以在后台异步地从服务器检索数据的想法,并且Web页和服务器之间的交互不限于提取页面的那一刻。 网页概念扩展到一个长期存在的Web应用程序,该应用程序通过与应用程序后端的持续通信与用户进行交互。 正在进行的通信所允许的一些示例是:
- 发送和接收信息
- 临时输入验证(例如,密码强度)
- 根据规则和在服务器上完成的分析自动完成用户输入
为了执行与客户端-服务器交互相关的任务,应用程序需要一个最佳的通信层,该层为每个通信任务提供适当的通信机制。
在本文中,了解构建通信层时要考虑的问题,并探索应在其中构建的不同机制。
做旧学校
在过去,网页和服务器之间的通信被认为是黑客行为。 只有通过使用不同HTML元素(不打算使用它们)才有可能。 这些元素的关键方面(允许其使用(或滥用))是它们旨在从服务器中获取文件。 然后,浏览器负责根据元素的类型解释文件。 元素是:
img
提取图像文件
script
提取JavaScript™文件
iframe
显示并可能获取HTML文件
这些元素旨在成为网站标记的一部分。 但是,通过使用JavaScript进行一些DOM操作,您可以动态地注入元素,并在页面生命周期中与服务器进行交互。 接下来的三个部分描述了如何使用这些元素。
忘却了:滥用<img>元素
img
元素的主要用途是从服务器获取图像并显示它。 要获取图像,浏览器将使用该元素的src
属性值的URL创建一个GET请求。 该值不受浏览器“相同来源策略”的限制; 因此,图像的URL 不限于该页的显示图像的领域。
你可以做什么和不能做什么
可以使用img
元素从任何URL执行GET调用。 然后,您可以从逻辑上调用其他服务器上的服务。
当心缓存
记住,GET调用可以在浏览器中缓存,也可以在任何网络节点上缓存。 如果使用< img
>元素来调用呼叫,则可能需要创建一个无法缓存的URL(例如,通过向其添加随机URL参数)。
但是,浏览器假定该GET调用的响应是图像文件,并照此处理(通过将其显示在屏幕上)。 如果响应实际上不是图像文件,则不能将img元素添加到DOM树中,因为GET请求是在设置src
属性时创建的(无论是否将img元素添加到页面中)。
您可以将img
元素主要用于“一劳永逸”类型的服务,在该服务中,服务器返回的响应与客户端无关。 它适用于遵循“服务器中发生的一切,留在服务器中”的规则的服务。
清单1显示了如何执行即发即弃调用。
清单1.忘却调用服务
<script type=”text/javascript”>
function fireAndForgetService(targetUrl){
// first we create an img object
var imgNode = document.createElement(“img”);
// then we set its src attribute to the url of the service we’d like to invoke
// when the next code line is executed the browser creates a GET request
// and sends it to targetURL
imgNode.src = targetUrl;
}
// calling the function with any url – cross site scripting is possible here
fireAndForgetService(“http://www.theTargetUrl.com/doSomething?param1Name:param1Value”);
</script>
提取并执行:使用<script>元素
如果您改为使用script
元素,则先前提到的有关img
元素的几乎所有内容都将起作用。 这种通信机制也不受浏览器“相同来源策略”的限制。
但是,< img
>和< script
>元素不同的一种方式是,当使用script
元素时,浏览器希望接收可以执行JavaScript代码。 这是一个非常强大的机制,不应轻易使用。 提取的脚本将被调用,并有权访问页面可以访问的所有内容,包括cookie,DOM,历史记录等。
你可以做什么和不能做什么
您应该在浏览器中运行的代码和获取的脚本之间定义某种协议。 如果要从自己的域中获取脚本,则该代码很可能熟悉应用程序代码的各种功能,实用程序和约束。 该协议基本上可以是同一应用程序的两个组件的集成。 作为请求的一部分,服务器可以接收应在浏览器中执行的部分代码,并且可以对其进行各种操作,例如处理国际化限制或其他特定于用户的修改。
JSON格式
JavaScript对象表示法(JSON)是描述JavaScript对象的一种方式。 这是一种非常强大的数据格式,可以在浏览器中快速转换为JavaScript对象。 相关主题具有有关JSON的更多信息。
当您需要从另一台服务器获取代码时,事情会变得更加有趣。 在这种情况下(如果该域是可信任的),则所获取的脚本不熟悉应用程序的结构,因此静态数据仅仅是可以获取的所有内容。 要在您的应用程序中处理此数据,您需要以某种方式将获取的内容与应用程序的代码集成在一起。 您可以使用JSONP概念,该概念基本上表明所获取的代码是一个JSON对象,该对象通过接受该对象的函数调用进行包装(或填充)。 (此调用称为回调。)该函数的名称作为URL参数发送,作为获取的脚本的URL的一部分,并且由收件人的域提供由该函数的名称包装的JSON对象。
清单2演示了如何基于JSONP执行客户端-服务器通信。
清单2. JSONP方法
<script type=”text/javascript”>
// the next function receives the following arguments:
// targetUrl – the url from which data is fetched and handled later as
// jsonp
// jsonpName – the name of the url parameter that the target url accepts and
// knows to read from the callback name
// callbackName – the name of the function that will handle the returned
// json object
function invokeJSONP(targetUrl, targetDomainJsonpName ,callbackName){
// first we create a script object
var scriptNode = document.createElement(“script”);
// set its type so upon return it would be executed
scriptNode.type = “text/javascript”;
// set its src attribute to the url of the fetched script
// and add to the url the callback name
scriptNode.src = targetUrl+”?”+ targetDomainJsonpName+”=”+callbackName;
// adding the script to the page to get it up and running
document.getElementsByTagName(“head”)[0].appendChild(scriptNode);
}
// calling the function with any url – cross site scripting is possible here
function handleJsonp(infoObject){
validateInfoObject(infoObject);
handleInfoObject(infoObject);
}
invokeJSONP (“http://targetUrl.com/provideJsonpData”,“jsonpCallback”, “handleJsonp”);
</script>
值得一提的微小差异。 使用< img
>元素时,不需要将其添加到DOM树中。 相反,当您执行脚本提取时, 除非将< script
>元素添加到DOM树中, 否则不会创建GET请求。
由目标域发布用于JSONP调用的API,尤其是应用程序中的参数名称,该名称应提供回调的名称。 API的其他部分应包括在响应主体中发送的JSON对象的结构。
在清单2中,目标域接受一个名为jsonpCallback
的URL参数(名称可能在不同的域中有所不同),该参数期望该域返回一个脚本,该脚本是对handleJsonp
的调用。 该脚本可能类似于清单3。
清单3.从目标域返回的JSONP
handleJsonp( {
‘height’:185,
‘units’:’cm’,
‘age’: 30,
‘favoriteFruit’:’apple’,
‘likesDogs’: true
}
);
向中间人寻求帮助:使用<iframe>元素
iframe
是一个元素,可让您将页面嵌入页面中。 如果两个页面来自同一域,则它们可能彼此通信并在彼此之间传递信息。
在Ajax应用程序中,通常使用这种范例通过驻留在主页中的iframe
元素来分隔用户交互和客户端-服务器通信的角色。 该元素将对用户隐藏,并且不会干扰应用程序的任何用户交互活动。
联合工作使您可以从服务器获取任何种类的内容,并可以进行表单提交而无需刷新页面-所有这些操作都是在后台进行的。
你可以做什么和不能做什么
与先前的机制都是构成页面的所有元素不同, iframe
元素本身就是页面。 它不限于特定种类的内容(例如图像)或处理(执行接收到的内容)。 因此,可以从任何服务器检索任何类型的数据并将其发送到任何服务器。 并且由于可以接收任何内容,因此您可以基于具有任何可能格式的数据执行交互,这为您在服务器端提供了更大的灵活性。 将数据发送到服务器可以基于表单提交。 除了GET之外,您还可以使用POST请求。 可以进行多部分请求,因此可以将来自客户端计算机的文件上载到服务器。 (请记住,所有页面刷新都会阻止与用户的其余交互。)
iframe
的使用并非完美无缺。 因为跨站点调用是有效的,所以应用程序的安全性可能会受到攻击。 此外,基于此机制的任何交互都会被推送到页面的历史对象中,这可能会使使用“后退/前进”操作导航的用户感到困惑。
使用iframe
隐藏iframe
隐藏iframe
方法有多种,从将iframe
置于屏幕外部到将其尺寸减小到零,几乎所有方法都可以使用。 您还可以将可见性样式设置为隐藏。
但是,您不能将其显示样式设置为none 。 如果这样做,则无法创建GET请求,并且无法从服务器获取所需的内容。
使用iframe
元素以编程方式从服务器中获取内容与使用script
元素相似,但有一个重要区别。 创建script
元素并将其连接到页面后,您需要将其隐藏,以使用户不会被屏幕上的内容所困扰。
您可以将iframe
元素用作表单提交的目标,从而防止表单提交导致的页面刷新。
清单4显示了如何使用iframe
元素作为应用程序标记的一部分来上传文件,而不是以编程方式执行客户端-服务器通信。
清单4.使用<iframe>上传文件
<!—a hidden iframe that is the target of the form that would be used to upload a file -->
<iframe id="IFrame" name="IFrame"
style="width:0px; height:0px; border:0px"
src="blank.html">
</iframe>
<!—the form is connected to the previous iframe by the target attribute, thus basically
reloading that hidden frame upon form submission -->
<form name="UploadFile" target="IFrame" method="POST"
action="http://myServer/fileUploadServiceURL"
enctype="multipart/form-data">
<input type="file" name="uploadFileNameId"/>
<input type="submit" value="Upload" name="submit"/>
</form>
用Ajax的方式来做
基于Ajax的Web应用程序通常充当服务器上运行的应用程序的客户端,从而导致通信密集型应用程序将数据来回发送至该服务器。 需要一种提供数据传输的机制。 作为应用程序的关键组件,该机制应尽可能轻巧且安全。 幸运的是,所有现代浏览器都配备了一个您可以用于此目的的对象:XMLHttpRequest(XHR)。 XHR实际上是轻量级的,它创建的请求仅限于从中检索页面的服务器。 它消除了所有跨站点脚本问题,并且只能传达文本。
你可以做什么和不能做什么
XHR对象的使用允许应用程序将信息发送到其服务器并从中获取数据。 与前面描述的机制相比,此机制具有多个优点:
可以使用任何类型的HTTP方法
因为最常见的现代服务器体系结构是基于REST原理的,所以您需要使用GET,PUT,POST和DELETE请求。 在客户端-服务器通信的核心中使用XHR对象可以实现RESTful服务器体系结构。 完成通知
通过此事件处理程序,可以确保在数据可用时执行依赖于从服务器获取的数据的代码。
页面历史中没有任何干预
XHR调用不会反映在页面的历史记录对象中,因此它不会偏离浏览器“后退”和“前进”操作的常用用法。
跨域资源共享
使用跨域资源共享( CORS )机制可以进行跨站点Ajax调用。 但是,CORS仍处于起步阶段,仅受少数浏览器支持,并且需要其他服务器端编码。
不允许跨站点脚本(XSS)
该应用程序缺乏执行XSS的能力,因此更加安全。 是否阻塞
- 同步,浏览器等待响应时不执行任何代码
- 异步,响应到达后可以在其中执行回调
XML或任何其他格式
如果响应为XML格式,则会为该响应数据创建一个完整的DOM树。 响应的原始文本内容也可用(当响应以另一种格式(例如JSON)到达时可以处理。
尽管如此,并不是所有的东西都是XHR对象的阳光和鲜花。 由于只能发送文本,因此您仍然需要使用iframe
将文件上传到服务器。 此外,在不同浏览器中创建此对象的方式也不同。
摘要
客户端与服务器的交互是任何现代Web应用程序的基础。 在本文中,您了解了可用于应用程序交互的常见机制。 并非每个应用程序都需要这里讨论的所有机制。 由您决定所需的内容以及如何使用它们。
许多JavaScript框架都附带了部分或全部Ajax通信机制的实现。 在决定使用哪个框架以及实施哪种机制时,请考虑这一点。
翻译自: https://www.ibm.com/developerworks/web/library/wa-aj-ajaxcomm/index.html
ajax服务器端