目录
一、AJAX示例
1.1、优点
1.2、缺点
1.3、jQuery AJAX示例
二、延迟对象(Deferred)
2.1、回调函数
2.2、deferred.done
三、跨域
3.1、什么是跨域
3.2、JSONP跨域
3.3、jQuery使用JSONP跨域
3.4、跨域资源共享(CORS)
3.5、小结
四、弹出层
五、模板引擎
5.1、Hello World
5.2、方法
5.3、与AJAX结合应用
六、示例下载
一、AJAX示例
AJAX全称为“Asynchronous JavaScript And XML”(异步JavaScript和XML) 是指一种创建交互式网页应用的开发技术、改善用户 体验,实现无刷新效果 。
1.1、优点
不需要插件 支持
优秀的用户 体验
提高Web程序的性能
减轻服务器和带宽的负担
1.2、缺点
浏览器对XMLHttpRequest对象的支持 度不足,几乎所有浏览器现在都支持
破坏浏览器“前进”、“后退”按钮的正常功能 ,可以通过简单的插件 弥补
对搜索 引擎的支持 不足
1.3、jQuery AJAX示例
在HTML5中对原生的AJAX核心对象XMLHttpRequest进行升级 ,也就是XHR2,功能 更加强大。
jQuery对AJAX封装的非常好,这里以简单的商品管理为示例使用jQuery完成AJAX应用。
Product.java bean:
名称 */
private String name;
/** 价格 */
private double price;
/**
图片 */
private String picture;
/** 详细 */
private String detail;
@Override
public String toString() {
return "Product [id=" + id + ",name=" + name + ",price=" + price + ",picture=" + picture + ",detail="
+ detail + "]";
}
public Product(int id,String name,double price,String picture) {
super();
this.id = id;
this.name = name;
this.price = price;
this.picture = picture;
}
public Product(int id,String picture,String detail) {
super();
this.id = id;
this.name = name;
this.price = price;
this.picture = picture;
this.detail = detail;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getPicture() {
return picture;
}
public void setPicture(String picture) {
this.picture = picture;
}
public String getDetail() {
return detail;
}
public void setDetail(String detail) {
this.detail = detail;
}
}
IProductService.java:
getAll();
/**
添加
* @return */
boolean add(Product entity);
/**根据编号获得产品对象*/
Product findById(int id);
/**根据编号获得产品对象
* @return */
boolean deleteById(int id);
}
ProductService.java:
products;
static {
products = new ArrayList<>();
Random random = new Random();
for (int i = 1; i <= 10; i++) {
Product product = new Product(i,"华为Mate9MHA-AL00/4GB RAM/全网通华为超级闪充技术双后摄设计" + random.nextInt(999),random.nextDouble() * 1000,"pic(" + i + ").jpg","产品详细");
products.add(product);
}
}
/*
* (non-Javadoc)
*
* @see com.gomall.service.IProductService#getAll()
*/
@Override
public List
getAll() {
return products;
}
/*
* (non-Javadoc)
*
* @see com.gomall.service.IProductService#add(com.gomall.bean.Product)
*/
@Override
public boolean add(Product entity) {
try {
entity.setId(products.size() + 1);
entity.setPicture("pic(" + entity.getId() + ").jpg"); // uploadify
// 上传 图片
products.add(entity);
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
/*
* (non-Javadoc)
*
* @see com.gomall.service.IProductService#findById(int)
*/
@Override
public Product findById(int id) {
for (Product product : products) {
if (product.getId() == id) {
return product;
}
}
return null;
}
/*
* (non-Javadoc)
*
* @see com.gomall.service.IProductService#deleteById(int)
*/
@Override
public boolean deleteById(int id) {
try {
Product product = findById(id);
if (product != null) {
products.remove(product);
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
}
ProductAction.java:
添加CORS信息*/
response.addHeader("Access-Control-Allow-Origin","*");
response.addHeader("Access-Control-Allow-Methods","GET,POST");
String json = mapper.writeValueAsString(productService.getAll());
out.append(json);
} else if(act.equals("del")){
/**向响应的头部中
添加 CORS信息*/
response.addHeader("Access-Control-Allow-Origin",POST");
int id=Integer.parseInt(request.getParameter("id"));
String json = mapper.writeValueAsString(productService.deleteById(id));
out.append(json);
}
else if(act.equals("add")){
/**向响应的头部中
添加 CORS信息*/
response.addHeader("Access-Control-Allow-Origin",POST");
String name=request.getParameter("name");
double price=Double.parseDouble(request.getParameter("price"));
String detail=request.getParameter("detail");
Product entity=new Product(0,name,price,"",detail);
String json = mapper.writeValueAsString(productService.add(entity));
out.append(json);
}
}
protected void doPost(HttpServletRequest request,IOException {
doGet(request,response);
}
}
运行结果:
删除 :
二、延迟对象(Deferred)
deferred对象就是jQuery1.5版以后新增加 的回调函数 解决方 案。
2.1、回调函数
先看一个示例:
首先,为什么要使用Deferred?
<
Meta charset="UTF-8">
回调
student.json文件 :{"name":"tom","id":"01"}
运行结果:
因为AJAX是异步执行的,类似高级语言中的多线程,当发起ajax请求时会有网络延迟,而代码 并没有在$.get的位置被阻塞,alert先执行,但数据并没有从远程获取 到,所以结果是undefined。
其实初学者经常会犯这种错误 ,如:
上面的代码 是有问题的,原因如前面的示例是一样的。怎么解决 ,如果你认为是异步带来的问题,当然通过同步是可以解决 的,如:
结果:
如果将所有的ajax请求修改 为同步的,则ajax的好处就大打折扣了,如果即要异步又要解决 上面的问题,可以使用回调方法 。
示例:
<
Meta charset="UTF-8">
回调
结果:
从这里看回调很完美,其实不然,实际开发中要复杂得多,如当第一个ajax请求完成才可以完成第二个,当第二个完成才可以完成第三个,可能最一个请求要等前面的所有请求都成功时才允许执行或才有条件执行,如
使用ajax编辑用户 信息,先加载用户 对象,再加载省,加载市,加县,可能代码 会这样写:
当回调越来越多,嵌套越深,代码 可读性就会越来越差。如果注册 了多个回调,那更是一场噩梦,幸好从jQuery1.5开始出现了延迟对象(deferred),可以解决 这个问题。
2.2、deferred.done
$.ajax()操作完成后,如果使用的是低于1.5.0版本的jQuery,返回的是XHR对象,你没法进行链式操作;如果高于1.5版,返回的是deferred对象,可以进行链式操作。
当延迟成功时调用 一个函数 或者数组函数 ,功能 与原success类似。
语法:deferred.done(doneCallbacks[,doneCallbacks])
返回值:Deferred Object
该参数可以是一个函数 或一个函数 的数组。当延迟成功时,doneCallbacks被调用 。回调执行是依照他们添加 的顺序。一旦deferred.done()返回延迟对象,延迟对象的其它方法 也可以链接 到了这里,包括 增加 .done()方法 。当延迟解决 ,doneCallbacks执行使用参数提供给 resolve或 resolveWith方法 依照添加 的顺序调用 。
示例代码 :
<
Meta charset="UTF-8">
延迟对象(deferred)
运行结果:
2.3、deferred.fail
语法:deferred.fail(failCallbacks[,failCallbacks])
返回值:Deferred Object
当延迟失败时调用 一个函数 或者数组函数 ,功能 与原回调方法 error类似。
该参数可以是一个函数 或一个函数 的数组。当延迟失败时,doneCallbacks被调用 。回调执行是依照他们添加 的顺序。一旦deferred.fail()返回延迟对象,延迟对象的其它方法 也可以链接 到了这里,包括 增加 .done()方法 。当延迟解决 ,doneCallbacks执行使用参数提供给 resolve或 resolveWith方法 依照添加 的顺序调用 。
示例:
<
Meta charset="UTF-8">
延迟对象(deferred)
运行结果:
2.4、deferred.always
语法:deferred.always(alwaysCallbacks,[alwaysCallbacks])
返回值:Deferred Object
当递延对象是解决 (成功,resolved)或拒绝(失败,rejected)时被调用 添加 处理程序,与回调方法 complete类似。
示例:
<
Meta charset="UTF-8">
延迟对象(deferred)
运行结果
成功时:
失败时:
2.5、deferred.then
deferred.then(doneFilter [,failFilter ] [,progressFilter ])
添加 处理程序被调用 时,递延对象得到解决 或者拒绝,一次指定多个事件。
所有三个参数(包括 progressCallbacks ,在jQuery的1.7 )可以是一个单独的函数 或一个函数 的数组。 其中一个参数,也可以为空,如果没有该类型的回调是需要的。或者,使用.done()或.fail()仅设置doneCallbacks或failCallbacks。当递延解决 ,doneCallbacks被调用 。若递延代替拒绝,failCallbacks被调用 。回调按他们添加 的顺序执行。一旦deferred.then返回延迟对象,延迟对象的其它方法 也可以链接 到了这里,包括 增加 .then()方法 。
示例:
<
Meta charset="UTF-8">
延迟对象(deferred)
结果:
2.6、应用延迟对象
前面的示例中我们都是使用jQuery ajax返回的deferred对象,其实我们也可以在自定义 的代码 中使用deferred对象,恰当的使用deferred对象或以优雅的解决 不少问题。
示例:
<
Meta charset="UTF-8">
延迟对象(deferred)
失败时:
成功时:
promise()在原来的deferred对象上返回另一个deferred对象,后者只开放与改变执行状态无关的方法 (比如done()方法 和fail()方法 ),屏蔽 与改变执行状态有关的方法 (比如resolve()方法 和reject()方法 ),从而使得执行状态不能被改变。
2.7、总结
(1) 生成 一个对象。
指定操作成功时的回调函数
指定操作失败时的回调函数
没有参数时,返回一个新的对象,该对象的运行状态无法被改变;接受参数时,作用为在参数对象上部署接口。
手动改变对象的运行状态为已完成,从而立即触发方法 。
这个方法 与正好相反,调用 后将对象的运行状态变为已失败,从而立即触发方法 。
.Deferred()生成 一个deferred对象。
(2)deferred.done()指定操作成功时的回调函数
(3)deferred.fail()指定操作失败时的回调函数
(4)deferred.promise()没有参数时,返回一个新的deferred对象,该对象的运行状态无法被改变;接受参数时,作用为在参数对象上部署deferred接口。
(5)deferred.resolve()手动改变deferred对象的运行状态为"已完成",从而立即触发done()方法 。
(6)deferred.reject()这个方法 与deferred.resolve()正好相反,调用 后将deferred对象的运行状态变为"已失败",从而立即触发fail()方法 。
(7).when() 为多个操作指定回调函数 。
除了这些方法 以外,deferred对象还有二个重要方法 ,上面的教程中没有涉及到。
(8)deferred.then()
有时为了省事,可以把done()和fail()合在一起写,这就是then()方法 。
如果then()有两个参数,那么第一个参数是done()方法 的回调函数 ,第二个参数是fail()方法 的回调方法 。如果then()只有一个参数,那么等同于done()。
(9)deferred.always()
这个方法 也是用来指定回调函数 的,它的作用是,不管调用 的是deferred.resolve()还是deferred.reject(),最后总是执行。
三、跨域
互联网上的主机由IP来标识,为了方便记忆,创建了域名系统.域名与IP对应,域名的作用是不用让你记复杂的IP地址,能唯一定位资源,URL的格式是协议://主机名.公司名称 .机构类型.地域类型:端口/路径,如
3.1、什么是跨域
JavaScript同源策略的限制,A域名下的JavaScript无法操作B或是C域名下的对象,如下所示:
假设页面:
客户端代码 d05.html,
6.4.9、跨域AJAX请求
6.4.9、跨域AJAX请求
另一个域下面一般处理程序,:
/// 根据
用户 编号获得
用户
///
public class FindUserById : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
String name = "";
int id = Convert.ToInt32(context.Request.Params["id"]);
if (id == 1001)
{
name = "Mark";
}
else if (id == 1002)
{
name = "Jack";
}
context.Response.Write(name);
}
public bool IsReusable
{
get
{
return false;
}
}
}
}
运行结果:
3.2、JSONP跨域
JSONP跨域是利用script脚本允许引用不同域下的js实现的,将回调方法 带入服务器,返回结果时回调。
2.1、JSONP跨域原理
客户端:
").html(obj.name).appendTo("body");
});
},"jsonp");