一、问题的提出

目前web前端开发,主流的思路是:

1)编写静态的html文件(不使用模板技术,与服务器无关)

2)页面通过ajax与服务器交互,进行数据的传输,数据格式为json格式

这里存在一个问题,因为有大量的与服务器的ajax交互,前端代码的编写与测试对服务器的依赖很大。这有时可能会影响前端的开发效率。

本文我们提出一种方法,就是通过用js模拟服务器的请求响应,使的前端代码可以独立开发和调试,当最后实际与服务器交互时,只需替换下api即可,工作量很小。

二、解决方案

具体的做法是:

1、定义一个js类,如:

function MockServer(){

}

2、定义一个方法,如:

MockServer.prototype.ajax = function(url,paras,handle){

}

正常情况下,页面中需要向服务器发送ajax请求,需要调用相应的ajax api (具体的api依赖所使用的框架,一般开发web前端都会使用某个或多个框架,如最常用的jquery框架)。但不管是使用哪个框架的ajax api,其核心的信息包括三个部分:

1)请求的url。 服务器针对不同的url会给出不同的处理。

2)js传给服务器的参数,通常是一个json对象

3)服务器处理返回消息的回调函数

我们这里提供的ajax方法的参数正好是这三部分内容。

这时编写js代码时,就先调用这个ajax方法发送请求。到时再替换具体框架的api,这个工作量相对很小的,只需替换下api即可,其它代码基本不用变。

上面定义的ajax中组装需要返回到浏览器的数据(是个json对象),然后调用调用者提供的handle回调函数,参数就是要返回的json对象。

因为ajax的请求时异步响应的,为了使流程更加真实,我们在这个ajax方法中使用setTimeout方法来实现异步的响应。该方法的实现代码如下:

MockServer.prototype.ajax = function(url,paras,handle){
var result={};
.............
//给result对象设置值,该result对象就是返回到ajax请求的数据
window.setTimeout(handle,parseInt(10*Math.random())+10,result);
}

可以看出,上面代码利用 Math.random 方法获取一个随机数(以便更加真实),然后设置定时器,当随机数时间到了,

就调用回调函数,参数是result对象。 在这之前,需要根据不同的url,给result设置不同的返回值,这个按照业务逻辑来处理就行了。

调用者的代码如:

  var mockServer = new MockServer();
mockServer.ajax("loadmyokr",{},function(result){
if(result.errorcode){
alert("操作失败,错误原因是:"+result.errorinfo);
return;
}
showData(result.data);
});

当和服务器真实交互时,将上面的api换成实际使用的api即可。甚至还可以进一步处理,这个api就保留,到时在这个api中再次封装即可。
这样js代码就几乎可以实现不用修改。

三、进一步深入

在实际的服务器代码中,数据是会持久化的,也就是说客户端与服务器交互引起的数据变化会持久化。

当页面重新刷新后,会获取到最新的变化后的数据。

如果我们只是在上面的ajax方法代码中根据业务需求封装返回客户端的json对象,这些都是在内存中操作的,因为MockServer类本身就是js类,存在于客户端。

一旦页面刷新,所有页面操作引起的数据变化都没了,每次刷新页面都会回到初始界面。

初始界面本身这个倒没有大问题。最大的问题是这样会导致客户端js的代码很可能考虑不全,存在逻辑错误或遗漏的地方。

为了更加真实的模拟服务器。

我们可以利用html5的 Web Storage APi 让这些模拟的数据持久化到客户端机器上。这样在交互过程中发生的数据变化都会被持久化下来。

一旦页面刷新后,也可以取到持久化的数据。这样就更加真实的模拟了服务器的行为。使得客户端的代码基本上就是真实的。

下面我们给出MockServer类的示例代码:

function MockServer(){
if(!window.localStorage["mydata"]){
window.localStorage["mydata"]="{}";
}
this.mydata = window.localStorage["mydata"];
} MockServer.prototype.ajax = function(url,paras,handle){
//下面这语句很重要,因为localStorage中存放的是键值对,
//目前大多浏览器支持的值都是字符串,需要调用JSON的api转换成json对象,以便于后续的处理
this.mydata = JSON.parse(this.mydata); //下面代码就是根据不同的url请求,对this.mydata对象中的内容进行读取和更新
//并设置返回给客户端的result对象
// this.mydata 变量不是必须的,这么做只是为了放便。
//这样对各url请求的处理就聚焦到对this.mydata对象的处理,不用关心存储等公共的事情了。
..... //下面这语句也很重要,因为前面处理的this.mydata已经是json对象,
//需要把它转换成字符串后才能存储到localStorage中
window.localStorage["mydata"] = JSON.stringify(this.mydata); //重新将保存到localStorage中的字符串值赋值给this.mydata变量
this.mydata = window.localStorage["mydata"]; //设置定时器,调用回调函数
window.setTimeout(handle,parseInt(10*Math.random())+10,result);
}

四、还能进一步吗

上满我们利用html5de WEB storage功能在浏览器本地对数据做持久化。

除此之外,我们还可以利用WEB sql database 功能在浏览器对数据做持久化。这么做会让模拟代码更接近服务器的处理代码(因为大部分场景下数据都是存在数据库的)。 如果这时服务器采用nodejs开发。也许很多客户端的代码和服务器的nodejs代码就能共享了。

五、小结

采用上的策略,我们很好地解决了web前端开发时对服务器的依赖。在我们的实际项目应用中反馈也是非常不错的。

这个也没有太多的技术含量。只是一个开发思路的转变。

这种思路其实不仅是让前端的开发更加方便。其实它也有利于客户端和服务器的接口定义更加合理。

在我们传统的开发方式中, 我们需要先协商客户端和服务器的接口(主要内容包括上面介绍的三部分,即url,请求参数,返回值)。

但是毕竟是事先定义的,可能再随着客户端的开发中,会发现这个预先定义的接口不太适合,这时又需要协商修改。

无形中会带来额外的工作量,包括维护的工作量,甚至会因为接口的同步不及时导致客户端无法正常运行。

而采用这种模拟的方式,客户端完全可以根据自己的需要设计api,并在开发的过程自由调整,一旦客户端代码定型后,只要提交一份需求给服务器即可,这个时候定义的接口一定是比较适合和稳定的。这样出来的api也是比较易于做自动化测试的。

这种做法尤其是在客户端和服务器分工开发的团队中非常适合,虽然我们现在鼓励全栈程序员,但前段技术和后端技术是有差异的,在实际的项目开发中大家的分工往往还是有侧重点的。

采用这种方式,客户端的开发者不用关心服务器采用的技术,可以聚焦在页面的设计、页面代码的编写中。

服务器代码的编写者一样可以不关心客户端,可以更加关注服务器代码的逻辑、性能、架构等方面。

WEB开发:如何用js来模拟服务器的ajax响应,不依赖服务器来编写前端代码的更多相关文章

  1. web开发与设计--js数据类型,js运营商

    1. js数据类型划分:号码值类型,布尔,串 由typeof能够看到什么类型的数据被详述. 举例: <span style="font-family:Microsoft YaHei;f ...

  2. web开发常用的js验证,利用正则表达式验证邮箱、手机、身份证等输入

    正则表达式验证 //邮箱 \-])+\.)+([a-zA-Z0-]{,})+$/; email = document.getElementById("email").value; ...

  3. 微信web开发的上传图片js接口

    $('.chooseImage').click(function(){ wx.chooseImage({ count: pic_num, // 默认9,大于9也是显示9 sizeType: ['com ...

  4. 超全的web开发工具和资源

    首页 新闻 产品 地图 动态 城市 帮助 论坛 关于 登录 注册 · 不忘初心,继续前进,环境云V2接口正式上线 · 环境云测点地图全新改版 · 祝福各位环境云用户中秋快乐!   平台信息 培训互动 ...

  5. web开发学习路线

    第一阶段: HTML+CSS: HTML进阶.CSS进阶.div+css布局.HTML+css整站开发. JavaScript基础: Js基础教程.js内置对象常用方法.常见DOM树操作大全.ECMA ...

  6. 如何学习web开发环境搭建和脚手架

    Web前端的学习路线 第一阶段: HTML+CSS: HTML进阶.CSS进阶.div+css布局.HTML+css整站开发. JavaScript基础: Js基础教程.js内置对象常用方法.常见DO ...

  7. 干货100+ 最超全的web开发工具和资源大集合

    干货100+ 最超全的web开发工具和资源大集合   作为Web开发者,这是好的时代,也是坏的时代.Web开发技术也在不断变化.虽然很令人兴奋,但是这也意味着Web开发人员需要要积极主动的学习新技术和 ...

  8. Snap.svg – 现代 Web 开发必备的 JavaScript SVG 库

    SVG 是一种很好的 Web 技术方案,可以用来创建互动,在任何大小的屏幕上都会很好看.与分辨率无关的矢量图形.而这里推荐的 Snap.svg 这个 JavaScript 可以让你像 jQuery 操 ...

  9. web开发学习之Http协议

    web入门 请求: request 浏览器向服务器发信息 响应:response 服务器回复浏览器 一个请求发出,一定有且仅有一个响应   http协议:对浏览器客户端余服务器的数据传输规范   ht ...

随机推荐

  1. jQuery File Upload

    jQuery File Upload介绍.............................................. 2 实现基本原理......................... ...

  2. docker4dotnet

    docker4dotnet #1 – 前世今生 & 世界你好   作为一名.NET Developer,这几年看着docker的流行实在是有些眼馋.可惜的是,Docker是基于Linux环境的 ...

  3. 面试题:对一个正整数n,算得到1需要的最少操作次数

    实现一个函数,对一个正整数n,算得到1需要的最少操作次数.操作规则为:如果n为偶数,将其除以2:如果n为奇数,可以加1或减1:一直处理下去.例子:func(7) = 4,可以证明最少需要4次运算n = ...

  4. 大数据时代之hadoop(五):hadoop 分布式计算框架(MapReduce)

    大数据时代之hadoop(一):hadoop安装 大数据时代之hadoop(二):hadoop脚本解析 大数据时代之hadoop(三):hadoop数据流(生命周期) 大数据时代之hadoop(四): ...

  5. 《Java虚拟机原理图解》 1.2.2、Class文件里的常量池具体解释(上)

    [last updated:2014/11/27] NO1.常量池在class文件的什么位置? 我的上一篇文章<Java虚拟机原理图解> 1.class文件基本组织结构中已经提到了clas ...

  6. Knockout快速扫盲

    1.Knockout.js是什么?   Knockout是一款很优秀的js库,它可以快速让你使用一个干净整洁的底层数据模型,即可创建一个富文本且具有良好显示和编辑功能的用户界面.任何时候你的ui需要自 ...

  7. CSS的clear属性

    以下引用自w3school clear 属性定义了元素的哪边上不允许出现浮动元素.在 CSS1 和 CSS2 中,这是通过自动为清除元素(即设置了 clear 属性的元素)增加上外边距实现的.在 CS ...

  8. HTML5 总结-音频-2

    HTML5 音频 音频格式 当前,audio 元素支持三种音频格式:   IE 9 Firefox 3.5 Opera 10.5 Chrome 3.0 Safari 3.0 Ogg Vorbis   ...

  9. werkzeug中reloader的实现

    在用flask开发时,如果把use_reloader设为True(debug设为True也能实现),那当你修改了app代码或调用环境发生改变时,服务器会自动重启,如下 * Detected chang ...

  10. Python学习之路——socket

    一.Socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信. socket服务端示例: import socke ...