在上一节我们介绍了客户端的几种代理,本节的主要内容是介绍如何使用服务器端代理,将重点介绍AjaxProxy,这是我们最常用的代理方式。

Ajax

web应用程序开发过程中,与服务器端交互的技术最常用的就是Ajax了。Ajax 是使用Javascript创建一个HttpRequest,采用异步的方式从服务器获取数据。我们先看一个简单的示例:

Ext.onReady(function () {
Ext.define('Person', {
extend: 'Ext.data.Model',
fields: ['name', 'age']
});
var store = Ext.create('Ext.data.Store', {
model: 'Person',
proxy: {
type: 'ajax',
url: rootUrl + 'sample/getjson',
reader: {
type: 'json',
root: 'users'
}
}
}); store.load(); var msg = [];
store.each(function (person) {
msg.push(person.get('name') + ' ' + person.get('age'));
}); Ext.MessageBox.alert('提示', msg.join('<br />'));
});

在这段代码中,首先定义了Model类Person,然后创建了Person类的数据仓库 store,store 使用了ajax代理,通过url向服务器请求数据,ajax代理的reader 配置项是告诉程序以何种方式读取请求到的数据。

我们从服务器返回的JSON字符串如下:

{users:[{name:'www.qeefee.com', age:1}, {name:'Tom', age:26}]}

大家先猜想一下运行结果?按照上一节的逻辑,此处应该弹出一个对话框,上面将内容内容显示出来,但真正运行的时候得到的却是空的内容,截图如下:

难道我们没有请求到数据?当然不是,如果你打开网络跟踪,会发现程序已经将成功得到了这段JSON字符串。那是为什么仍然是空呢?

原因是当我们调用load()方法的时候,我们告诉store去请求数据吧,然后store就使用ajax的方式请求url,注意,ajax 是异步的,所以当我们调用load()方法以后,马上执行输出的时候,store仍然是空的,可能它还在等待服务器响应数据。

所以,在我们使用ajax方式加载数据的时候,就需要为load() 方法添加一个callback 方法,当数据加载完成以后,再callback方法中进行数据输出,修改load方法的调用:

store.load({
callback: function (records, operation, success) {
if (success) {
var msg = [];
store.each(function (person) {
msg.push(person.get('name') + ' ' + person.get('age'));
}); Ext.MessageBox.alert('提示', msg.join('<br />'));
}
}
});

刷新页面,这次才是我们想要的结果:

ajax 带参数的请求

我们打开网络跟踪,刷新页面,跟踪我们所有的网络请求:

找到getjson的请求,点击查看明细:

在这个URL中可以看到,ExtJS 其实已经为我们添加了一些参数,包括 page、start和limit。这些参数是从哪儿来的呢?

在使用ajax进行请求的时候,ajax代理会调用自身的read方法,该方法的第一个参数是Ext.data.Operation 类型,它用来配置我们如何进行请求。我们在load 方法中可以通过配置项传递一些参数,load在调用read方法时将这些参数传递过去,read则会根据这些参数生成Ext.data.Operation 的一个实例。所以,我们可以这样来传递参数:

store.load({
page: 2,
limit: 10,
params: {
name:'QF'
},
callback: function (records, operation, success) {
if (success) {
var msg = [];
store.each(function (person) {
msg.push(person.get('name') + ' ' + person.get('age'));
}); Ext.MessageBox.alert('提示', msg.join('<br />'));
}
}
});

我们再次跟踪请求,传递的地址变成了 /SampleExtJS/sample/getjson?_dc=1374141754304&name=QF&page=2&start=25&limit=10

通过传递这些参数,我们可以完成分页、查询等操作。

JsonP

在Javascript 中,由于跨域操作存在很严重的安全隐患,所以浏览器不允许我们直接使用ajax 进行跨域请求。当用到跨域请求的时候,我们可以使用请求javascript 资源的形式,将要请求的Json数据作为Javascript 代码加载到浏览器中(浏览器不会阻止跨域的资源请求,资源包括Javascript、css、图片等)。具体做法:使用 Javascript 动态添加一个script 标签,将要请求的资源URL 作为src的属性传递过去(请求url中通常包含一个callback方法名的参数),服务器端对请求的数据进行包装,然后返回给客户端。

在ExtJS 中我们可以轻松的使用JsonP代理进行跨域的数据请求:

//创建Store
var store = Ext.create('Ext.data.Store', {
model: 'Person',
proxy: {
type: 'jsonp',
url: 'http://www.abc.com/sampleextjs/sample/getjsonp',
reader: {
type: 'json',
root:'users'
}
}
});

在测试中,我们的本机名是localhost,所以对域名abc.com进行数据请求是跨域的操作(我们在第二节 bootstrap.js的工作方式 中已经对本机的hosts文件进行了修改,将abc.com也指向本地)。

然后添加服务器段代码,在SampleController 中添加getJsonP方法:

public string GetJsonP()
{
string callback = Request["callback"];
if (string.IsNullOrEmpty(callback))
callback = "callback"; Response.ContentType = "text/javascript";
return callback + "({users:[{name:'www.qeefee.com', age:1}, {name:'QF', age:26}]})";
}

这段代码中,我们首先得到请求中的callback参数,如果没有则默认为“callback”字符串。然后将拼接好的JSON字符串作为参数传递给callback方法,我们在这里返回的字符串要遵循Javascript 语法。

编译项目,然后刷新页面,打开开发人员工具,跟踪网络请求,你会发现在进行网络请求的时候,ExtJS 会自动为请求地址添加回调方法,url中包含参数:callback=Ext.data.JsonP.callback1,根据传入的callback参数,我们服务器返回的字符串为:

Ext.data.JsonP.callback1({ users: [{ name: 'www.qeefee.com', age: 1 }, { name: 'QF', age: 26 }] })

这段代码可以被当做Javascript代码在加载完成后执行。我们的运行结果如图:

ExtJS 提供的这种方式大大简化了我们客户端的处理代码,方便我们进行JsonP跨域请求。

JsonP代理的其它操作跟Ajax代理基本一直,不再过多介绍。接下来看一下Rest代理。

Rest

Rest 指的是什么呢?根据我个人的理解,我觉得Rest像是一种开发规范,由于Http请求是无状态的,所以在对网络资源进行请求的时候,我们通常会将状态(要执行的操作:增删改查等,以及要操作的数据)作为参数传递给服务器,而Rest 则规定,HttpMethod 的GET、POST、PUT、DELETE分别对应不同的操作(Get 对应查找、PUT对应更新、POST对应新增、DELETE对应删除)。关于更完整的Rest,请参照《深入浅出REST》。

在ASP.NET MVC 中,我们可以使用Web API 轻松的实现RESTful应用程序。

我们首先在服务器段用C#代码定义一个Model:

public class User
{
public string name { get; set; }
public int age { get; set; }
}

然后创建针对User类操作的UserController,它需要继承自ApiController,代码如下:

public class UserController : ApiController
{
public static List<User> UserList = null;
static UserController()
{
if (UserList == null)
{
UserList = new List<User>();
UserList.Add(new User() { name = "www.qeefee.com", age = 1 });
UserList.Add(new User() { name = "QF", age = 26 });
}
} // GET api/<controller>
public List<User> Get()
{
return UserList;
} // GET api/<controller>/5
public List<User> Get(string name)
{
List<User> result = new List<User>();
foreach (User item in UserList)
{
if (item.name == name)
result.Add(item);
} return result;
} // POST api/<controller>
public void Post([FromBody]User user)
{
UserList.Add(user);
} // PUT api/<controller>/5
public void Put([FromBody]User user)
{
UserList.Add(user);
} // DELETE api/<controller>/5
public void Delete(string name)
{
for (int i = UserList.Count - 1; i >= 0; i--)
{
User user = UserList[i];
if (user.name == name)
{
UserList.RemoveAt(i);
}
}
}
}

由于API针对不同的HttpMethod 选择不同的操作,所以当我们直接使用浏览器请求API的时候,我们将得到第一个Get方法的返回结果:

由于我们没有指明返回的数据格式,所以默认为我们将对象转换为Xml。我们在ExtJS中使用Rest代理:

//创建Store
var store = Ext.create('Ext.data.Store', {
model: 'Person',
proxy: {
type: 'rest',
url: rootUrl + 'api/user/',
reader: {
type: 'json'
}
}
});

然后使用load方法加载数据:

store.load({
callback: function (records, operation, success) {
var msg = [];
store.each(function (item) {
msg.push(item.get('name') + ' ' + item.get('age'));
});
Ext.MessageBox.alert('提示', msg.join('<br />'));
}
});

此时跟踪Network请求:

红框中的是我们请求的URL和得到的数据的预览。我们程序完成解析后会弹出提示:

此时我们可以对store执行一些CRUD操作,跟踪一下网络请求和服务器段代码,查看一下Rest代理是如何工作的。

Direct

Direct 代理使用Ext.Direct 向服务器发送数据。

Ext.Direct 技术的好处是,允许你像调用Javascript 方法一样调用服务器端代码。我们将在后面的章节中详细的介绍 Ext.Direct。当我们定义好Ext.Direct 以后,才能够使用Direct代理来请求数据。

例如我们在API中看到的代码:

Ext.define('User', {
extend: 'Ext.data.Model',
fields: ['firstName', 'lastName'],
proxy: {
type: 'direct',
directFn: MyApp.getUsers,
paramOrder: 'id' // Tells the proxy to pass the id as the first parameter to the remoting method.
}
});
User.load(1);

本节内容介绍了服务器端代理的使用方法,这些基础性的内容比较枯燥,但却是学习ExtJS 复杂控件的基础,在这些内容的基础上,我们才能够更加轻松的学习Grid、Tree 等复杂控件。

ExtJS 4.2 教程-06:服务器代理(proxy)的更多相关文章

  1. 转--htaccess语法教程 apache服务器伪静态规则教程

    转自:http://blog.csdn.net/qingli518/article/details/9118361 htaccess语法教程apache服务器伪静态规则教程 注:如果你是为了找Disc ...

  2. [译]Vulkan教程(06)验证层

    [译]Vulkan教程(06)验证层 What are validation layers? 什么是验证层? The Vulkan API is designed around the idea of ...

  3. 浅谈linux 下,利用Nginx服务器代理实现ajax跨域请求。

    ajax跨域请求对于前端开发者几乎在任何一个项目中都会用到,众所周知,跨域请求有三种方式: jsonp; XHR2 代理: jsonp: 这种应该是开发中是使用的最多的,最常见的跨域请求方法,其实aj ...

  4. Apache服务器代理与缓存

    Apache服务器代理与缓存 1.代理  正向代理:             反向代理:   mod_proxy模块 apache实现代理和网关的关键模块.加载mod_proxy模块:LoadModu ...

  5. iTOP-4412开发板-实战教程-ssh服务器移植到arm开发板

    本文转自迅为开发板:http://www.topeetboard.com 在前面实战教程中,移植了“串口文件传输工具”,整个移植过程是比较简单的,而且我 们没有做任何协议方面的了解,只是“配置”+“编 ...

  6. JAVA设计模式-动态代理(Proxy)示例及说明

    在Mybatis源码解析,一步一步从浅入深(五):mapper节点的解析文章的最后部分,我们提到了动态代理的概念,下面我们就简单了解一下动态代理. 一,概念 代理设计模式的目的就是在不直接操作对象的前 ...

  7. node解决跨域和服务器代理详解代码

    node中有很多解决服务器代理的插件,这里简介一个:express-http-proxy 之前网上查的使用node解决跨域的插件,有很多,例如,cors,koa2,这里解决跨域问题我拿原生解决的,ex ...

  8. Head First 设计模式 —— 13. 代理 (Proxy) 模式

    思考题 如何设计一个支持远程方法调用的系统?你要怎样才能让开发人员不用写太多代码?让远程调用看起来像本地调用一样,毫无瑕疵? P435 已经接触过 RPC 了,所以就很容易知道具体流程:客户端调用目标 ...

  9. 详解Linux交互式shell脚本中创建对话框实例教程_linux服务器

    本教程我们通过实现来讲讲Linux交互式shell脚本中创建各种各样对话框,对话框在Linux中可以友好的提示操作者,感兴趣的朋友可以参考学习一下. 当你在终端环境下安装新的软件时,你可以经常看到信息 ...

随机推荐

  1. .NetCore 分页控件实现原理处理以及条件分页处理

    说明 自定义一个类继承TagHelper,注意自定义类的 必须以TagHelper结尾,这个有点类是属性 Attribute的写法 protected TagHelper(); // // 摘要: / ...

  2. .NetCore生产环境下构建Consul(单个DC数据中心)的服务器健康检查

    下载最新的consul程序 consul 启动方式有两种 server 和client 默认是client 如果你不需要记录数据可以用 consul agent -dev 来启动 consul age ...

  3. 【AtCoder】ARC101题解

    C - Candles 题解 点燃的一定是连续的一段,枚举左端点即可 代码 #include <bits/stdc++.h> #define enter putchar('\n') #de ...

  4. 跟厂长学PHP7内核(四):生命周期之开始前的躁动

    上一章我们对PHP的源码目录结构有了初步了解,本章我们继续从生命周期的维度对PHP进行剖析. 一.概览 生命周期是什么呢?你可以把它看作执行过程,PHP的生命周期也就是它从开始执行到结束执行的过程. ...

  5. java List/ArrayList 解惑

    导读:祖传挖坟派学习方法(宝儿姐友情支持) 第一部分  List简介 第二部分  何为ArrayList 第三部分  代码示例 第四部分  吹牛 如果你急需想搞清楚一些问题可以先看这里的总结 再后续看 ...

  6. html (第四本书第七章浮动参考)

    课上1 <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8 ...

  7. mysql索引原理剖析

    一.索引的原理 所谓索引,即是快速定位与查找,那么索引的结构组织要尽量减少查找过程中磁盘I/O的存取次数(B+树相比B树,其非叶子节点占用更小的空间,可以有更多非叶子节点存放在再内存中,减少大量的IO ...

  8. 笔记本光驱位置装SSD固态硬盘(亲自试验)

    我的笔记本买的早了,2010年的联想Z460,速度有点慢,本来想换台电脑,想想还是算了,没有太大必要.固态硬盘便宜了,于是在原来的光驱位置装了一个256G的SSD固态硬盘,现在的性能能达到刚买来时的1 ...

  9. VC6微软正则表达式greta使用案例

    #include <string> #include "regexpr2.h" using namespace std; using namespace regex;/ ...

  10. Linux学习笔记08—如何关闭防火墙

    Linux系统下面自带了防火墙iptables,iptables可以设置很多安全规则.但是如果配置错误很容易导致各种网络问题,那么如果要关闭禁用防火墙怎么操作呢,咗嚛本经验以centos系统为例演示如 ...