ajax 封装ajax方法通信道是什么意思,怎么实现,有什么好处

实现基于项目约定的 ajax 通用性封装 - WEB前端 - 伯乐在线
& 实现基于项目约定的 ajax 通用性封装
ajax 实现的基本原理是 XMLHttpRequest 或 fetch api。简单的 ajax 请求,只需要几行代码即可实现:
JavaScript
const url = '/rest/xxx';
const xhr = new XMLHttpRequest();
xhr.open('GET', url);
// xhr.open('POST', url);
xhr.responseType = 'json';
xhr.addEventListener('load', function() {
console.log('sucess:', xhr.response);
xhr.send();
// xhr.send(formdata)
12345678910
const url = '/rest/xxx';const xhr = new XMLHttpRequest();xhr.open('GET', url);// xhr.open('POST', url);xhr.responseType = 'json';xhr.addEventListener('load', function() {&&&&console.log('sucess:', xhr.response);});xhr.send();// xhr.send(formdata)
使用 fetch API 则更为简单:
JavaScript
window.fetch(url).then((res) =& {
res.json();
}).then((result) =& {
console.log(result);
}, (err) =& {
console.log(err);
window.fetch(url).then((res) =& {&&&&res.json();}).then((result) =& {&&&&console.log(result);}, (err) =& {&&&&console.log(err);})
但是在实际项目开发中,很少会直接这么用,因为存在兼容性问题,易用性/通用性也不够。例如 GET/POST 请求、文件上传、图片获取等,实现方式都有较大的差异。
为什么要做更进一步的 ajax 封装
前端开发者应该都很熟悉 jQuery 中的 $.ajax/$.post/$.get 这些方法,在各种框架或库中也存在着不尽相同的 ajax API 方法实现。类似这样的 xhr api 封装屏蔽了不同平台的差异性,简化了 xhr 的使用,在一些简单的应用中似乎已经可以满足需求了,但在中大型应用中还远远不够。
这些实现满足了易用性的需求,却难以完成基于业务特性和接口约定的通用逻辑处理。我在实际的项目中,看到了太多相似而重复的类似如下的代码:
JavaScript
function getAAA(callback, errCallback) {
$.get('/rest/aaa').then( function (result) {
if (result.code !== 200) {
errCallback(result);
callback(result);
}, function (err) {
errCallback(err);
function getBBB() {
123456789101112131415
function getAAA(callback, errCallback) {&&&&$.get('/rest/aaa').then( function (result) {&&&&&&&&if (result.code !== 200) {&&&&&&&&&&&&errCallback(result);&&&&&&&&&&&&return;&&&&&&&&}&&&&&&&&callback(result);&&&&}, function (err) {&&&&&&&&errCallback(err);&&&&});}&function getBBB() {&&&&//...}
这样的代码有什么问题呢?getAAA、getBBB…… 这样的样板代码产生了相似的大量逻辑,特别是在 ajax 请求特别多的中后台系统中,这使得逻辑实现有失优雅,又难以维护。想象一下需要在 ajax 过程中增加一个统一参数处理与上报的情况,你需要动多少地方。
在一个 ajax 请求的生命周期中,你可能需要做的事情有很多。如果你有考虑过如下列举的一些需求,那么应该已经在做更符合项目约定的 ajax 方法封装了:
更简洁的代码逻辑
统一的数据获取方式、环境切换、数据 mock 处理
接口约定与出错处理
前端数据缓存(memory 与 session、local 级别)
通用的回调处理 (成功/失败处理,xss 注入等数据预处理)
按钮状态等处理
公共参数获取与上报
api 埋点性能收集(如超长耗时、网络超时、50x 出错等)
简单来说,在请求执行前,你可能需要加载动画、禁用按钮、组装通用参数等等;在请求执行过程中,需要禁止继续操作;在执行成功/失败后,需要对数据作正确性验证、对加载动画作恢复处理、性能收集等等。这些繁多又相似的操作,如果在每一个涉及 ajax 请求的地方都去硬代码实现,那是多么烦人的一件事情。
相同或相似功能应尽量书写可复用代码实现,函数化、模块化、参数化是实现代码可复用的关键技巧,也是高质量编码的基本要求。简单的复用实现可以是一个函数,更复杂完善一些就成了通用性组件、库或框架。
基于项目约定的 ajax 封装实现
对比 xhr 与 $.ajax 方式,jQuery 包装了的代码显然更为简洁。这样做的好处也是显而易见的,去除冗余,调用简单,更易维护。
下面简单阐述我们针对前述需求的理解和实现。
我们封装了一个通用性的 ajax api,在 ajax 请求发起前、请求过程中、请求成功和失败这几个阶段和状态,通过抽象各种参数的方式,将基于业务特性的不同功能需求交给具体项目应用来定义和处理,由此以取得广泛的适用性。
前端数据缓存 (memory 与 session、local 级别)
基于 ajax 的应用,进入页面时可能同时发起了多个请求,这对服务器的并发性增加了更高的要求。其实很多万年不变的元数据类信息,完全可以在前端缓存起来。对于已知在一定时间范围内不会变化的数据(如离线计算的隔日数据结果集),也可以缓存起来。这样在一定程度上避免了 API 请求浪费,也使得复杂网络环境下的前端响应更为迅速。至于缓存到什么程度,则需要根据具体的数据应用来设定。一般来说:
对于单页应用,可能缓存到内存就够了。
对于多页应用,可以缓存到 sessionStorage。
对于确实万年不变的数据,可以缓存到 localStorage [或加上个过期时间]。
我们在通用性封装中做了这样的处理:
设置 cache 和 fromCache 参数:cache 约定是否缓存本次请求,fromCache 本次请求是否优先尝试从缓存中获取。其类型可为:memory、sessionStorage 和 localStorage。
这样只需要在需要的时候配置对应参数,就可以简单实现数据的缓存读写。示例:
JavaScript
import adm from 'ajax-data-model';
const data = {typeId: 2};
const param = {
url: '/rest/user/list',
cache: 'localStorage', // 获取到数据后,缓存到 localStorage
fromCache: 'localStorage', // 优先尝试从 localStorage 获取数据
cacheName: 'userlist_type_' + data.typeId // 缓存读写时使用的 key,以请求参数区分
adm.get(param).then((result) =& {}, (err) =& {});
// 从 localStorage 中删除缓存
adm.delete('userlist_type_' + data.typeId, 'localStorage');
1234567891011121314
import adm from 'ajax-data-model';const data = {typeId: 2};const param = {&&&&data,&&&&url: '/rest/user/list',&&&&cache: 'localStorage', // 获取到数据后,缓存到 localStorage&&&&fromCache: 'localStorage', // 优先尝试从 localStorage 获取数据&&&&cacheName: 'userlist_type_' + data.typeId // 缓存读写时使用的 key,以请求参数区分};&adm.get(param).then((result) =& {}, (err) =& {});&// 从 localStorage 中删除缓存adm.delete('userlist_type_' + data.typeId, 'localStorage');
通用的预处理、公共参数上报处理
很多业务都涉及到公共参数的上报。我们设置了一个 fnAjaxBefore 参数方法,用于在 ajax 前回调处理请求相关参数。示例:
JavaScript
* ajax 请求开始前回调方法
{Object} config - ajax 请求配置,由于是引用传参,可在这里通过修改它实现 mock 数据等功能
* @return {Object} 返回修改后的 config
fnBeforeAjax(config) {
// 示例:增加通用上报参数
cofig.data = $.extend({}, config.data, {
username: window.Cookie.get('userName'),
now: new Date().getTime()
// 还可以针对 config 中特定约定的参数做更多的约定处理
123456789101112131415
/** * ajax 请求开始前回调方法 * @param&&{Object} config - ajax 请求配置,由于是引用传参,可在这里通过修改它实现 mock 数据等功能 * @return {Object} 返回修改后的 config*/fnBeforeAjax(config) {&&&&// 示例:增加通用上报参数&&&&cofig.data = $.extend({}, config.data, {&&&&&&&&username: window.Cookie.get('userName'),&&&&&&&&now: new Date().getTime()&&&&});&&&&// 还可以针对 config 中特定约定的参数做更多的约定处理&&&&&return config;}
通过 fnAjaxBefore 参数的回调方式,还可以方便地实现环境切换、钩子调用、数据模拟等功能需求。
接口约定与出错处理
ajax 请求失败了可以统一处理:你可以发送上报日志,或者直接忽略它。如果是网络中断,也可以在 localStorage 里缓存它,在下次有成功的网络链接时再进行上报。反正具体做什么和怎么做由你说了算。
当得到了请求成功了,但它是否正确呢?后端 API 的返回数据对于前端来说是不可信的,如果你还无法理解这一句话,那么想想因接口问题发生的各种报错甚至导致单页应用功能失效的情况。如果没有一个基于约定的统一的数据验证和容错处理,那么业务代码中肯定会处处存在各种相似的 if else。
我们为此设置了 fnAjaxDone 参数方法,当请求完成时回调,在该方法中实现接口约定,以及更多的自定义验证行为。
举个例子,我们约定接口返回信息中包含 code 字段,当其值为 200 时表示数据处理成功,否则为其他对应的状态,需由后端返回 message 字段,告诉前端到底哪里出了问题。示例:
JavaScript
fnAjaxDone(result, callback, errCallback, config) {
let success =
// code 为 200 认为是成功数据
if (result && result.code === 200) {
// 你也可以在 config 自定义参数中设置更多更严格的验证方式,需求由你来定
// if (config.fnValidate && config.fnValidate(result)) {}
if (callback) {
callback(result);
if (errCallback) {
errCallback(result);
// 全局性系统提示,设置为 false,则不提示,适合由用户自定义错误处理的情况
if (config.tipConfig !== false) {
result.message = result.message || '系统错误';
// 错误数据 alert 通知
this.alert(result.message);
12345678910111213141516171819202122232425262728
fnAjaxDone(result, callback, errCallback, config) {&&&&let success = false;&&&&&// code 为 200 认为是成功数据&&&&if (result && result.code === 200) {&&&&&&&&// 你也可以在 config 自定义参数中设置更多更严格的验证方式,需求由你来定&&&&&&&&// if (config.fnValidate && config.fnValidate(result)) {}&&&&&&&&if (callback) {&&&&&&&&&&&&callback(result);&&&&&&&&}&&&&&&&&&success = true;&&&&} else {&&&&&&&&if (errCallback) {&&&&&&&&&&&&errCallback(result);&&&&&&&&}&&&&&&&&&// 全局性系统提示,设置为 false,则不提示,适合由用户自定义错误处理的情况&&&&&&&&if (config.tipConfig !== false) {&&&&&&&&&&&&result.message = result.message || '系统错误';&&&&&&&&&&&&// 错误数据 alert 通知&&&&&&&&&&&&this.alert(result.message);&&&&&&&&}&&&&&}&&&&&return success;}
有同学可能会问到,如果网络或者服务器挂了(一般为 30x/40x/50x 错误),获取不到数据,又该怎么办呢?我们为这种状态设置了一个 fnAjaxFail 参数:
JavaScript
fnAjaxFail(err, config) {
let msg = err.responseText || err.statusText || '';
if (msg.length & 200) {
msg = msg.slice(0, 200) + '...';
// API 异常上报
if (window.__MZBH) {
window.__MZBH({
fi: window.location.origin + config.url, // 文件、路径
stk: '' //报错代码所在的函数片段,不一定都有
if (0 === err.status) {
this.alert('登录超时');
window.location.reload();
} else if (false !== config.errAlert) {
// errAlert = false 时禁止 40x/50x 等错误的全局提示
this.alert('数据请求失败: ' + msg);
1234567891011121314151617181920212223242526
fnAjaxFail(err, config) {&&&&let msg = err.responseText || err.statusText || '';&&&&&if (msg.length & 200) {&&&&&&&&msg = msg.slice(0, 200) + '...';&&&&}&&&&&// API 异常上报&&&&if (window.__MZBH) {&&&&&&&&window.__MZBH({&&&&&&&&&&&&msg,&&&&&&&&&&&&mg: msg,&&&&&&&&&&&&fi: window.location.origin + config.url, // 文件、路径&&&&&&&&&&&&li: 0,&&&&&&&&&&&&stk: '' //报错代码所在的函数片段,不一定都有&&&&&&&&}, 2);&&&&}&&&&&if (0 === err.status) {&&&&&&&&this.alert('登录超时');&&&&&&&&window.location.reload();&&&&} else if (false !== config.errAlert) {&&&&&&&&// errAlert = false 时禁止 40x/50x 等错误的全局提示&&&&&&&&this.alert('数据请求失败: ' + msg);&&&&}}
状态处理、耗时等性能收集
为了防止多次点击导致的重复提交,或在 ajax 执行时进行进度处理,你总是需要去根据实际情况写不同的逻辑代码。
在通用性请求封装中,我们提供了一个 fnWaiting 参数方法,结合具体请求中的参数,就可以制定符合业务需求的状态处理。还可以在该方法中统计和上报 ajax 超长请求耗时的情况。
例如,我们约定通过具体请求中的 waiting 参数的配置,在请求发起时禁用它并启用按钮的 loading 动画,在请求完成时恢复它。实现示例:
JavaScript
* ajax 开始/结束时的状态处理
* 例如单击按钮后,在开始时禁用按钮,结束时恢复它;
* 再例如,在 ajax 开始时启用页面动画,结束时关闭页面动画。
config.waiting - 参数内容可根据 `fnWaiting` 具体的处理来设置。例如这里为:
* `{$btn:$btn, text:"请求中..", defaultText: "提交"}`
{Number} time - 存在值时在 ajax 结束调用,值为 ajax 消耗的时间;省略时在 ajax 开始调用
* @return {void}
fnWaiting(config, time) {
const waiting = config.
// 开发状态下打印日志
if ('development' === process.env.NODE_ENV && time) {
console.trace('ajax 请求消耗时间:', time);
// 示例:根据 time 区分 ajax 开始与结束,分别做不同的处理
// 这里以处理按钮状态为例,waiting 参数则为关键: {$btn, text, defaultText}
if (!waiting || !waiting.$btn || !waiting.$btn.length) {
// 超长请求耗时的日志上报...
// if (time & waiting.timeout || 5000) {
// 启动 api 上报...
window.__MZBH('ajax_long_time', time, config.url);
if (!time) {
// 请求前,启动点击按钮的动画
waiting.$btn.data('defaultText', waiting.$btn.html())
.html(waiting.text || '&i class="fa fa-spinner fa-spin"&&/i& 请求中...')
.addClass('disabled').prop('disabled', true);
// 请求结束后,恢复按钮状态
setTimeout(function () {
// 连续提交延时处理,两次连续提交不能超过 200 ms
waiting.$btn.html(waiting.defaultText || waiting.$btn.data('defaultText'))
.removeClass('disabled').prop('disabled', false);
12345678910111213141516171819202122232425262728293031323334353637383940414243
/** * ajax 开始/结束时的状态处理 * 例如单击按钮后,在开始时禁用按钮,结束时恢复它; * 再例如,在 ajax 开始时启用页面动画,结束时关闭页面动画。 * @param&&{Object}&&config.waiting - 参数内容可根据 `fnWaiting` 具体的处理来设置。例如这里为: * `{$btn:$btn, text:"请求中..", defaultText: "提交"}` * @param&&{Number} time - 存在值时在 ajax 结束调用,值为 ajax 消耗的时间;省略时在 ajax 开始调用 * @return {void} */fnWaiting(config, time) {&&&&const waiting = config.waiting;&&&&&// 开发状态下打印日志&&&&if ('development' === process.env.NODE_ENV && time) {&&&&&&&&console.trace('ajax 请求消耗时间:', time);&&&&}&&&&&// 示例:根据 time 区分 ajax 开始与结束,分别做不同的处理&&&&// 这里以处理按钮状态为例,waiting 参数则为关键: {$btn, text, defaultText}&&&&if (!waiting || !waiting.$btn || !waiting.$btn.length) {&&&&&&&&return;&&&&}&&&&&// 超长请求耗时的日志上报...&&&&// if (time & waiting.timeout || 5000) {&&&&//&&&& // 启动 api 上报...&&&&//&&&& window.__MZBH('ajax_long_time', time, config.url);&&&&// }&&&&&if (!time) {&&&&&&&&// 请求前,启动点击按钮的动画&&&&&&&&waiting.$btn.data('defaultText', waiting.$btn.html())&&&&&&&&&&&&.html(waiting.text || '&i class="fa fa-spinner fa-spin"&&/i& 请求中...')&&&&&&&&&&&&.addClass('disabled').prop('disabled', true);&&&&} else {&&&&&&&&// 请求结束后,恢复按钮状态&&&&&&&&setTimeout(function () {&&&&&&&&&&&&// 连续提交延时处理,两次连续提交不能超过 200 ms&&&&&&&&&&&&waiting.$btn.html(waiting.defaultText || waiting.$btn.data('defaultText'))&&&&&&&&&&&&&&&&.removeClass('disabled').prop('disabled', false);&&&&&&&&}, 200);&&&&}}
adm 项目及实现核心 API
adm 项目地址在这里:
该实现基于 jQuery,使用了 jQuery.Deferred 实现 Promise 风格的回调接口。后续会考虑无 jQuery 依赖的实现版本。
通过全局性参数的方式,我们解决了通用性问题。从易用性的角度,API 应当尽量简单。核心 API 参考:
setSettings 设置全局性参数。在应用初始化时,全局设置,以实现基于接口约定的规则。
get 获取数据方法(GET 方式)
save 保存数据方法(POST 方式)
delete 删除数据
clear 清空数据
post save 方法的简化
getJSON get 方法的简化
具体用法可参见:
最后,欢迎分享你的经验。如果你有更好的想法,请不吝赐教。
关于作者:
可能感兴趣的话题
关于伯乐前端
伯乐前端分享Web前端开发,包括JavaScript,CSS和HTML5开发技术,前端相关的行业动态。
新浪微博:
推荐微信号
(加好友请注明来意)
– 好的话题、有启发的回复、值得信赖的圈子
– 分享和发现有价值的内容与观点
– 为IT单身男女服务的征婚传播平台
– 优秀的工具资源导航
– 翻译传播优秀的外文文章
– 国内外的精选文章
– UI,网页,交互和用户体验
– 专注iOS技术分享
– 专注Android技术分享
– JavaScript, HTML5, CSS
– 专注Java技术分享
– 专注Python技术分享
& 2017 伯乐在线Ajax是什么?工作原理是什么?_百度知道
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。
Ajax是什么?工作原理是什么?
我有更好的答案
他说它是“Asynchronous JavaScript + XML的简写”。Ajax的工作原理
Ajax的核心是JavaScript对象XmlHttpRequest。该对象在Internet Explorer 5中首次引入;重新显示的范例,则服务器数据只刷新列表而不是整个页面。 直接编辑表格数据,而不是要求用户导航到新的页面来编辑数据。对于Ajax。最重要的是,而不是刷新整个页面,用户甚至不知道浏览器正在与服务器通信:Web站点看起来是即时响应的。 提升站点的性能,这是通过减少从服务器下载的数据量而实现的,在开始之前。简而言之,XmlHttpRequest使您可以使用JavaScript向服务器提出请求并处理响应,而不阻塞用户,Web站点强制用户进入提交&#47,它遵循传统的提交/等待&#47,当用户单击Edit时,可以将静态表格刷新为内容可编辑的表格,以至于用户界面的可用性已经落后。
一切皆有可能:动态更新购物车的物品总数,无需用户单击Update并等待服务器重新发送整个页面,让我们介绍一个现有的Web站点;JavaScript堆栈创建“桌面风格的(desktop-like)”可用性。
通常,因为它最终允许开发人员和设计人员使用标准的HTML&#47。
在创建Web站点时,“我们没有可投入UI的时间”或“不能用HTML实现”。但是;CSS&#47,在Ajax中,如果用户在分页列表上单击Next!但愿它能够激发您开始开发自己的基于Ajax的站点。然而,在J2EE中,开发人员过于关注服务和持久性层的开发,就可以使用JavaScript和CSS来相应地更新UI,用户的动作总是与服务器的“思考时间”同步。Ajax提供与服务器异步通信的能力,从而使用户从请求&#47,它由几种蓬勃发展的技术以新的强大方式组合而成。Ajax包含,以下Web站点证明,这些理由再也站不住脚了。
虽然Ajax所需的基础架构已经出现了一段时间,但直到最近异步请求的真正威力才得到利用。能够拥有一个响应极其灵敏的Web站点确实激动人心、只读的数据,它是一种支持异步请求的技术,Web应用程序不必完全依赖于从服务器重新载入页面来向用户呈现更改。一切似乎就在瞬间发生:基于XHTML和CSS标准的表示; 使用Document Object Model进行动态显示和交互; 使用XMLHttpRequest与服务器进行异步通信; 使用JavaScript绑定一切。
这非常好,但为什么要以Ajax命名呢?其实术语Ajax是由Jesse James Garrett创造的,常常会听到这样的话。实际上。用户单击Done之后,就可以发出一个Ajax请求来更新服务器,并刷新表格,使其包含静态:BackPack Google Suggest Google Maps PalmSphere
所有这些Web站点都告诉我们;等待/重新显示范例,服务器只会返回新的总量值,因此所需的带宽仅为原来的百分之一。 消除了每次用户输入时的页面刷新。例如Ajax用来描述一组技术。在Ajax之前。简而言之,在涉及到用户界面的响应灵敏度时,基准设得更高了。定义Ajax
Adaptive Path公司的Jesse James Garrett这样定义Ajax:
Ajax不是一种技术。例如,在Amazon的购物车页面,当更新篮子中的一项物品的数量时,会重新载入整个页面,这必须下载32K的数据。如果使用Ajax计算新的总量,它使浏览器可以为用户提供更为自然的浏览体验,在客户端执行屏幕更新为用户提供了很大的灵活性。下面是使用Ajax可以完成的功能;响应的循环中解脱出来。借助于Ajax,可以在用户单击按钮时。在一个典型的J2EE开发周期中,使用JavaScript和DHTML立即更新UI,并向服务器发出异步请求,以执行更新或查询数据库。当请求返回时
服务器端在页面内写入结果文本,这个过程和普通的web开发没有任何区别。所不同的只是。从一个控件换到另外一个控件又会有一个漫长的学习曲线,学Ajax前,一定要好好研究一番JavaScript,一般来讲.net的Ajax开发显得更加“高效”或者是“神秘”,都是封装了这个处理过程的结果。   观点二,你的JavaScript水平就基本过关了。同时对DOM模型也可以算有一个基本的了解:CSS   用JavaScript控制CSS其实很简单.3,并让随后的字母变为大写就可以作为属性使用了、方法和事件,那就得不偿失了。以Asp.net为例,它的定制特性可以使得只要在方法前加上[ajax method]类似这样的标志就可以称为一个异步方法,相信这使得Asp。  观点一:选择符 {background-color:学好JavaScript   在大多数人看来,JavaScript总不是那么一种正规的语言。这段文本可以是xml格式,也可以是一个Html片段。DOM模型就规定了这些对象所具有的属性:DOM模型是Ajax最本质的技术   之所以没有把XMLHttpRequest列为最本质的技术Ajax和服务器端技术毫不相关;DOM模型是Ajax最本质的技术,例如:element.style.backgroundColor=&#f00&。通过这些性质,可以对一个已经显示于浏览器的页面进行内容的修改,例如增加节点;Ajax点缀:CSS ,随便copy一段就碰巧能运行,学过c之类的人,一看也能看懂,不是直接显示在页面,基本上每个DOM对象都有一个style对象;-&去掉,不论何种Ajax技术,服务器端都是返回的一个纯文本流,再由客户端来处理这个文本,并将其内容交给JavaScript处理.js),也可以是一段JavaScript脚本,或者仅是一个字符串。服务器端仅仅是作为一个数据接口,客户端使用XMLHttpRequest对象来请求这个页面,如果能顺利看懂prototype框架的代码(如。同样记住一条,任何对服务器端的请求仅仅是返回纯文本,客户端在异步获取结果后,或者其他的数据类型,而完全可以自己来实现。   观点四。   观点五:Ajax点缀:prototype-1、修改节点位置,删除节点等等。javascript作为一种脚本语言,其语法的确不是很严格,而是由客户端的Javascript脚本处理后再显示在页面。至于各种控件所谓的能返回DataSet对象,Date对象,因为本人觉得它实在是太简单了,它只是可以让浏览器在后台请求一个页面.1。真正的核心应该是:DOM模型,即文档对象模型。在DOM模型里,Html标记都被认为是一个对象,例如,但并不妨碍其完成诸多复杂的任务:div对象,而且在浏览器中常常有脚本错误提示,所以潜意识觉得总不能付之以大任。事实上,要学好Ajax,这就完全是一种错误的看法。所以应该从底层了解其,况且Ajax实在不是什么高深的技术。其实任何东西的最底层其实都是简单的,但如果封装了这些底层的东西,事情会变得复杂和难以理解,table对象等等。由于很多控件封装了客户端和服务器端的通信过程,因此很多问题也因通信而起,我们不一定要依赖于封装好的处理过程。   观点三:在使用Ajax控件前理解它们的实现   使用Ajax控件的确可以提高效率,但如果你空中楼阁般使用控件,而更多的事情则被封装了,没有JavaScript,就没有Ajax。所以本人强烈建议:Ajax和服务器端技术毫不相关   严格的说,与传统web开发相比。而不仅仅是一个innerHTML属性这么简单,虽然这是一个很有用的属性;在使用Ajax控件前理解它们的实现;在css是,只要把css属性里的&quot。事实上,Ajax是完完全全的客户端技术;学好JavaScript
为您推荐:
其他类似问题
您可能关注的内容
ajax的相关知识
换一换
回答问题,赢新手礼包

我要回帖

更多关于 ajax封装函数 的文章

 

随机推荐