JavaScript学习统计(二)——延迟对象、跨域、模板引擎、弹出层、AJAX示例

5.叁 、与AJAX结合使用

示范脚本:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>商品管理</title>
        <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
        <style type="text/css">
            @CHARSET "UTF-8";
            * {
                margin: 0;
                padding: 0;
                font-family: microsoft yahei;
                font-size: 14px;
            }

            body {
                padding-top: 20px;
            }

            .main {
                width: 90%;
                margin: 0 auto;
                border: 1px solid #777;
                padding: 20px;
            }

            .main .title {
                font-size: 20px;
                font-weight: normal;
                border-bottom: 1px solid #ccc;
                margin-bottom: 15px;
                padding-bottom: 5px;
                color: blue;
            }

            .main .title span {
                display: inline-block;
                font-size: 20px;
                background: blue;
                color: #fff;
                padding: 0 8px;
                background: blue;
            }

            a {
                color: blue;
                text-decoration: none;
            }

            a:hover {
                color: orangered;
            }

            .tab td,
            .tab,
            .tab th {
                border: 1px solid #777;
                border-collapse: collapse;
            }

            .tab td,
            .tab th {
                line-height: 26px;
                height: 26px;
                padding-left: 5px;
            }

            .abtn {
                display: inline-block;
                height: 20px;
                line-height: 20px;
                background: blue;
                color: #fff;
                padding: 0 5px;
            }

            .btn {
                height: 20px;
                line-height: 20px;
                background: blue;
                color: #fff;
                padding: 0 8px;
                border: 0;
            }

            .abtn:hover,
            .btn:hover {
                background: orangered;
                color: #fff;
            }

            p {
                padding: 5px 0;
            }

            fieldset {
                border: 1px solid #ccc;
                padding: 5px 10px;
            }

            fieldset legend {
                margin-left: 10px;
                font-size: 16px;
            }

            .pic {
                height: 30px;
                width: auto;
            }

            #divFrom {
                display: none;
            }
        </style>
    </head>

    <body>

        <div class="main">
            <h2 class="title">商品管理</h2>
            <table border="1" width="100%" class="tab" id="tabGoods">
                <tr>
                    <th>编号</th>
                    <th>图片</th>
                    <th>商品名</th>
                    <th>价格</th>
                    <th>详细</th>
                    <th>操作</th>
                </tr>
            </table>
            <p style="color: red" id="message"></p>
            <p>
                <a href="#" class="abtn" id="btnSave">添加</a>
                <input type="submit" value="删除选择项" class="btn" />
            </p>
            <div id="divFrom">
                <form id="formPdt">
                    <fieldset>
                        <legend>添加商品</legend>
                        <p>
                            <label for="name">
                    名称:
                </label>
                            <input type="text" name="name" id="name" />
                        </p>
                        <p>
                            <label for="price">
                    价格:
                </label>
                            <input type="text" name="price" id="price" />
                        </p>
                        <p>
                            <label for="detail">
                    详细:
                      </label>
                            <textarea id="detail" name="detail" cols="60"></textarea>
                        </p>
                    </fieldset>
                </form>
            </div>
        </div>

        <link rel="stylesheet" type="text/css" href="js/artDialog6/ui-dialog.css" />
        <script src="js/artTemplate3/template.js" type="text/javascript" charset="utf-8"></script>
        <script src="js/jQuery1.11.3/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script>
        <script src="js/artDialog6/dialog-min.js" type="text/javascript" charset="utf-8"></script>
        <!--[if (IE 8)|(IE 9)]>
        <script src="js/jquery.transport.xdr.min.js" type="text/javascript" charset="utf-8"></script>
        <![endif]-->
        <script type="text/html" id="tmpl">
            {{each list as pdt}}
            <tr>
                <td>{{pdt.id}}</td>
                <td><img src="http://localhost:8087/JavaScript001{{pdt.picture}}" class="pic"></td>
                <td>{{pdt.name}}</td>
                <td>{{pdt.price | round:'¥'}}</td>
                <td>{{pdt.detail}}</td>
                <td>
                    <a href="#" class="abtn del" data-id={{pdt.id}}>删除</a>
                </td>
            </tr>
            {{/each}}
        </script>
        <script type="text/javascript">
            var app = {
                url: "http://localhost:8087/JavaScript001/", //提供服务的域名
                add: function() {
                    var d = dialog({
                        title: '添加商品',
                        content: $('#divFrom').html(),
                        okValue: '添加',
                        modal: true,
                        backdropOpacity: 0.3,
                        ok: function() {
                            var that = this;
                            $.ajax({
                                type: "post",
                                data: $(".ui-dialog #formPdt").serialize() + "&act=add",
                                success: function(data) {
                                    if(data) {
                                        app.log("添加成功!");
                                        app.loadAll();
                                        that.close();
                                    } else {
                                        app.log("添加失败!");
                                    }
                                }
                            });
                            return false;
                        },
                        cancelValue: '关闭',
                        cancel: function() {
                            alert('你点了取消按钮')
                        },
                        onclose: function() {
                            alert("关闭了");
                        }
                    });

                    d.show();
                },
                del: function() {
                    id = $(this).data("id");
                    var that = $(this);
                    $.ajax({
                        type: "get",
                        data: {
                            "id": id,
                            "act": "del"
                        },
                        success: function(data) {
                            if(data) {
                                that.closest("tr").remove();
                                app.log("删除成功!");
                            } else {
                                app.log("删除失败!");
                            }
                        }
                    });
                },
                loadAll: function() {
                    $.ajax({
                        type: "get",
                        data: {
                            "act": "getAllCORS"
                        },
                        success: function(data) {
                            $("#tabGoods tr:gt(0)").remove();
                            $("#tabGoods").append(template("tmpl",{list:data}));
                        }
                    });
                },
                init: function() {
                    /*动态绑定删除事件*/
                    $("#tabGoods").on("click", "a.del", {}, app.del);
                    /*绑定添加事件*/
                    $("#btnSave").click(app.add);
                    /*设置全局AJAX默认值*/
                    $.ajaxSetup({
                        dataType: "json",
                        url: app.url + "Product?type=meat-and-filler&format=json",
                        beforeSend: app.ajaxBefore,
                        complete: app.clearMsg,
                        error: function(xhr, textStatus, errorThrown) {
                            app.log("错误" + textStatus + errorThrown);
                        }
                    });

                    //为模板引擎定义辅助函数
                    template.helper("round",function(value,mark){
                        return (mark||"")+Math.round(value);
                    });

                    this.loadAll();
                },
                clearMsg: function() {
                    this.box.remove();
                },
                ajaxBefore: function() {
                    this.box = dialog({
                        modal: true
                    });
                    this.box.show();
                },
                log: function(msg) {
                    $("#message").html(msg);
                }
            };

            app.init();
        </script>
    </body>
</html>

运作结果:

图片 1

三、跨域

互连网上的主机由IP来标识,为了有利于回忆,成立了域名系统.域名与IP对应,域名的意义是决不让您记复杂的IP地址,能唯一定位财富,UPAJEROL的格式是商量://主机名.集团名称.机构类型.地域类型:端口/路径,如http://www.zhangguo.com.cn:8080/products/list.do?id=1\#a1 

图片 2

3.肆 、跨域能源共享(COLacrosseS)

同源策略(same origin policy)的范围下非同源的网站之间不或许发送 ajax
请求的。

w3c 指出了跨源财富共享CO中华VS即Cross Origin Resource
Sharing(跨来源财富共享),就是我们所熟识的跨域请求。

跨域能源共享(COENVISIONS)是一种互连网浏览器的技术专业,它为Web服务器定义了一种艺术,允许网页从不同的域访问其财富。
CORS与JSONP相比:
壹 、 JSONP只可以促成GET请求,而COLANDS帮衬具有类型的HTTP请求。
2、使用CO奥迪Q5S,开发者可以运用普通的XMLHttpRequest发起呼吁和拿到多少,比起JSONP有更好的错误处理。
③ 、JSONP紧要被老的浏览器帮助,它们往往不帮衬CO大切诺基S,而一大半现代浏览器都早就支撑了COPRADOS。

图片 3

CO本田UR-VS 将请求分为两类:不难请求和非不难请求:

3.① 、什么是跨域

JavaScript同源策略的限定,A域名下的JavaScript不大概操作B或是C域名下的靶子,如下所示:

一旦页面:http://store.company.com/index.html

图片 4

 

图片 5

客户端代码d05.html,http://localhost:8087/jQuery601\_JAVA/d05.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>6.4.9、跨域AJAX请求</title>
</head>
<body>
    <h2>6.4.9、跨域AJAX请求</h2>
    <h2 id="message"></h2>
    <button type="button" id="btnAjax">ajax请求</button>
    <script type="text/javascript" src="js/jQuery/jquery.min.js"></script>
    <script type="text/javascript">
        $("#btnAjax").click(function() {
            $.get("http://localhost:12833/Action/FindUserById.ashx",{"id":1001},function(data){
                log(data);
            },"text");
        });

        function log(msg) {
            $("#message")[0].innerHTML += msg + "<br/>";
        }
    </script>
</body>
</html>

另三个域底下一般处理程序,http://localhost:12833/Action/FindUserById.ashx:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace jQuery601_DotNet.Action
{
    /// <summary>
    /// 根据用户编号获得用户
    /// </summary>
    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;
            }
        }
    }
}

运维结果:

图片 6

3.2、JSONP跨域

JSONP跨域是应用script脚本同意引用分裂域下的js达成的,将回调方法带入服务器,重回结果时回调。

2.一 、JSONP跨域原理

客户端:

    <body>
        <script type="text/javascript">
            /*回调方法*/
            function show(data) {
                alert(data);
            }
        </script>
        <script src="http://localhost:8087/JavaScript001/Product?act=area&callback=show" type="text/javascript" charset="utf-8"></script>
    </body>

服务器:

            String callback=request.getParameter("callback");
            out.append(callback+"('"+new Date()+"')");

结果:

图片 7

 图片 8

服务器重临一段javascript,通过点名的格局名调用。从图中得以看到,使用JSONP的款型调用已经不再是透过XMLHTTPRequest对象,而是一块调用。

5.1、Hello World

演示代码:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>artTemplate</title>
    </head>
    <body>
        <div id="result">
        </div>
        <script src="js/artTemplate3/template.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/html" id="template1">
            {{if isShow}}
              <h2>姓名:{{name}}</h2>
              <ul>
              {{each hobbies as hobby index}}
                 <li>
                     {{index+1}} {{hobby}}
                 </li>
              {{/each}}
              </ul>
            {{/if}}
        </script>
        <script type="text/javascript">
            var data={
                isShow:true,
                name:"Tom",
                hobbies:["看书","上网","运动","电影","购物"]
            };
            //用数据与模板渲染(render)出结果
            var html=template("template1",data);
            document.getElementById("result").innerHTML=html;
        </script>
    </body>
</html>

运营结果:

图片 9

变化的代码:

<h2>姓名:Tom</h2>
<ul>
    <li>
        1 看书
    </li>
    <li>
        2 上网
    </li>
    <li>
        3 运动
    </li>
    <li>
        4 电影
    </li>
    <li>
        5 购物
    </li>
</ul>

六 、示例下载

coding: https://coding.net/u/zhangguo5/p/javascript001/git

服务器: https://coding.net/u/zhangguo5/p/javascript001_java/git

github:  https://github.com/zhangguo5/javascript01 

第二版:

前端:https://git.coding.net/zhangguo5/javascript_01.git

后台:https://git.coding.net/zhangguo5/SpringMVC08.git

一、AJAX示例

AJAX全名叫“Asynchronous JavaScript And XML”(异步JavaScript和XML)
是指一种成立交互式网页应用的开发技术、改革用户体验,完毕无刷新功效。

图片 10

2.7、总结

(1) $.Deferred() 生成2个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() 为三个操作钦命回调函数。

(8)deferred.then() 有时为了方便,可以把done()和fail()合在一起写,那就是then()方法。借使then()有八个参数,那么首先个参数是done()方法的回调函数,第一个参数是fail()方法的回调方法。要是then()只有二个参数,那么等同done()。

(9)deferred.always() 这么些点子也是用来内定回调函数的,它的职能是,不管调用的是deferred.resolve()如故deferred.reject(),最终总是执行。

2.3、deferred.fail

语法:deferred.fail(failCallbacks[,failCallbacks])

返回值:Deferred Object

当延迟失利时调用2个函数或许数组函数,功效与原回调方法error类似。

该参数可以是二个函数或3个函数的数组。当延迟失利时,doneCallbacks被调用。回调执行是依照他们添加的顺序。一旦deferred.fail()重回延迟对象,延迟对象的其余方法也可以链接到了此地,包涵扩充.done()方法。当延迟化解,doneCallbacks执行使用参数提需求resolve或 resolveWith方法按照添加的顺序调用。

示例:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>延迟对象(deferred)</title>
    </head>
    <body>
        <script src="js/jQuery1.11.3/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            $.get("stu.json", "json").done(function(stu) {
                console.log(stu.name);
            }).fail(function(xhr, status, errorThrown){
                alert("xhr:"+xhr+",status:"+status+",errorThrown:"+errorThrown);
            });
        </script>
    </body>
</html>

运营结果:

图片 11

3.4.2.扑朔迷离请求

如说你须要发送PUT、DELETE等HTTP动作,大概发送Content-Type:
application/json的内容就必要利用复杂请求了。

初叶发送的是一种”预请求”,此时作为服务端,也亟需重临”预回应”作为响应。预请求实际上是对服务端的一种权限请求,唯有当预请求成功重临,实际请求才起来施行。预请求以OPTIONS形式发送,当中同样包涵域,并且还富含了两项CO奥迪Q5S特有的故事情节

代码:

        <script type="text/javascript">
            $.ajax({
                type:"PUT",
                url:"http://localhost:8080/mvc08/pdt",
                contentType:"application/json;charset=utf-8",
                dataType:"json",
                success:function(data){
                    console.log(data);
                }
            });
        </script>

结果:

图片 12

Access-Control-Allow-Origin(必含)
和精炼请求一样的,必须含有一个域,不能是*号

Access-Control-Allow-Methods(必含)

那是对预请求当中Access-Control-Request-Method的死灰复燃,这一复苏将是五个以逗号分隔的列表。即便客户端或许只请求某一方法,但服务端依然可以回来全体允许的方法,以便客户端将其缓存。

Access-Control-Allow-Headers(当预请求中涵盖Access-Control-Request-Headers时务必含有)

那是对预请求当中Access-Control-Request-Headers的还原,和方面一样是以逗号分隔的列表,可以回去全数扶助的底部。

Access-Control-Allow-Credentials(可选)
– 和简易请求当中功效一样。

Access-Control-Max-Age(可选)
– 以秒为单位的缓存时间,允许时应该尽或然缓存。

2.5、deferred.then

deferred.then(doneFilter [, failFilter ] [, progressFilter ])

累加处理程序被调用时,递延对象拿到化解大概拒绝,一次内定多少个事件。

怀有多个参数(包罗progressCallbacks ,在jQuery的1.7
)可以是1个独门的函数或一个函数的数组。
其中八个参数,也可以为空,假使没有该项目的回调是亟需的。可能,使用.done()或.fail()仅设置doneCallbacks或failCallbacks。当递延化解,doneCallbacks被调用。若递延代替拒绝,failCallbacks被调用。回调按他们添加的种种执行。一旦deferred.then重返延迟对象,延迟对象的其它措施也得以链接到了此地,包罗扩大.then()方法。

示例:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>延迟对象(deferred)</title>
    </head>
    <body>
        <script src="js/jQuery1.11.3/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            $.get("student.jsonx", "json").then(function(stu) {
                console.log(stu.name);
            }, function(data, status, errorThrown) {
                console.log("data:" + data + ",status:" + status + ",errorThrown:" + errorThrown);
            });
        </script>
    </body>
</html>

结果:

图片 13

2.壹 、回调函数

先看壹个示范:

首先,为啥要利用Deferred?

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>回调</title>
    </head>
    <body>
        <script src="js/jQuery1.11.3/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            var student;
            $.get("student.json",function(data){
                student=data;
            },"json");
            alert(student);
        </script>
    </body>
</html>

student.json文件:{“name”:”tom”,”id”:”01″}

运作结果:

图片 14

因为AJAX是异步执行的,类似高级语言中的多线程,当发起ajax请求时会有网络延迟,而代码并从未在$.get的地点被打断,alert先实施,但数量并不曾从远程获取到,所以结果是undefined。

骨子里初学者日常会犯那种不当,如:

            function getStudentById(id){
                $.get("students.do",{"id":id},function(stu){
                    return stu;
                },"json");
            }

上边的代码是反常的,原因如前方的言传身教是如出一辙的。怎么消除,假使您觉得是异步带来的题材,当然通过共同是可以消除的,如:

            $.ajax({
                type:"get",
                url:"student.json",
                async:false,  /*非异步,同步*/
                success:function(data){
                    student=data;
                }
            });

结果:

图片 15

假使将装有的ajax请求修改为一起的,则ajax的补益就大促销扣了,固然即要异步又要化解地点的标题,可以使用回调方法。

示例:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>回调</title>
    </head>
    <body>
        <script src="js/jQuery1.11.3/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
           /*callback是一个当ajax请求成功时的回调方法*/
            function getStudent(callback) {
                $.get("student.json", function(data) {
                    callback(data);
                }, "json");
            }

            /*调用getStudent函数,传入参数,参数也是一个函数*/
            getStudent(function(stu){
                alert(stu.id);
            });

            /*把一个方法作为参数传递给另一个方法可以认为是委托,如C++中的函数指针类似*/
            getStudent(function(stu){
                alert(stu.name);
            });
        </script>
    </body>
</html>

结果:

 图片 16

从那边看回调很周密,其实不然,实际开发中要复杂得多,如当第1个ajax请求完结才方可完结第四个,当第四个到位才得以成功第多少个,只怕最三个请求要等前边的具备请求都事业有成时才同意实施或才有标准化执行,如

使用ajax编辑用户新闻,先加载用户对象,再加载省,加载市,加县,大概代码会这样写:

            $.get("url1",function(){
                $.get("url2",function(){
                    $.get("url3",function(){
                      ...
                   });
                });
            });

当回调愈多,嵌套越深,代码可读性就会更为差。假设注册了多少个回调,那更是一场恶梦,万幸从jQuery1.5起来出现了延期对象(deferred),可以缓解这些难点。

3.4.1.简短请求

匡助get/post/put/delete请求,例如重返Access-Control-Allow-Origin:*,可是不允许自定义header且会忽略cookies,且post数据格式有限量,只协理‘text/plain’,’application/x-www-urlencoded’and’multipart/form-data’,其中’text/plain’暗中同意辅助,前边二种必要上面的预检请求和服务器协商。

简不难单请求对应当规则,因此对简易请求的概念为:

(1) 请求方法是以下二种方法之一:

HEAD
GET
POST

(2)HTTP的头消息不高于以下两种字段:

Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain

简简单单请求的一对响应头及解释如下:

Access-Control-Allow-Origin(必含)-
不可省略,否则请求按失利处理。该项控制数据的可知范围,假如指望多少对任何人都可知,可以填充”*”。

Access-Control-Allow-Credentials(可选)

该项标志着伏乞当中是还是不是蕴涵cookies音信,唯有3个可选值:true(必为题写)。假如不带有cookies,请略去该项,而不是填写false。这一项与XmlHttpRequest2对象当中的withCredentials属性应保持一致,即withCredentials为true时该项也为true;withCredentials为false时,省略该项不写。反之则导致请求败北。

Access-Control-Expose-Headers(可选) –
该项规定XmlHttpRequest2对象当中getResponseHeader()方法所能得到的附加音讯。平日状态下,getResponseHeader()方法只可以取得如下的消息:

Cache-Control
Content-Language
Content-Type
Expires
Last-Modified
Pragma

当你必要拜访额外的音讯时,就须求在这一项当中填写并以逗号进行分隔

示例:

劳动器端:

package com.zhangguo.springmvc08.action;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(name = "ProductServlet",value = "/pdt")
public class ProductServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //设置允许CORS的域名,如果是所有则使用*
        response.addHeader("Access-Control-Allow-Origin","*");
        response.getWriter().write("{\"name\":\"Book\"}");
    }
}

客户端:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>跨域</title>
    </head>
    <body>
        <script src="../js/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            //跨域Get请求
            $.get("http://localhost:8080/mvc08/pdt", function(data) {
                console.log("Get:"+data.name);
            }, "json");

            //跨域Post请求
            $.post("http://localhost:8080/mvc08/pdt", function(data) {
                console.log("Post:"+data.name);
            }, "json");
        </script>
    </body>

</html>

结果:

图片 17

八、作业

8.一 、请完成三个简易的分布式应用,使用Java作为服务器对外发布服务,PC客户端落成“品牌或货物”的管制,移动端达成如下列表:

  • a)、分析出数据库的宏图,建库、建表 (MySQL)
  • b)、成立后台项目,完成陆个劳务,可以行使RETSFul (IDEA)
  • c)、创立PC Web项目(HBuilder),使用AJAX消费后台提供的5个劳务
    ,达成扩充、删除、修改、查询作用
  • d)、创立App项目(HBuilder),先成功页面的静态布局,使用AJAX调用服务
  • e)、注意跨域、可以选择三方的UI框架,但界面需完全相同
  • f)、在PC Web中,添加,删除,编辑、详细作用请使用artDialog弹出层
  • g)、在PC Web与App中请使用artTemplate渲染页面HTML

图片 18

系统结构如下:

图片 19

 参考网站:https://m.dianping.com/

1.3、jQuery AJAX示例

在HTML5中对原生的AJAX主题对象XMLHttpRequest举办进步,也等于XH揽胜极光2,效用越来越强硬。 

jQuery对AJAX封装的格外好,那里以不难的货品管理为示范使用jQuery达成AJAX应用。

图片 20

Product.java bean:

package com.gomall.bean;

/***
 * 产品
 * 
 * @author Administrator
 *
 */
public class Product {
    /** 编号 */
    private int id;
    /** 名称 */
    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 name, double price, 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:

package com.gomall.service;

import java.util.List;

import com.gomall.bean.Product;

public interface IProductService {

    /**获得所有*/
    List<Product> getAll();

    /**添加
     * @return */
    boolean add(Product entity);

    /**根据编号获得产品对象*/
    Product findById(int id);

    /**根据编号获得产品对象
     * @return */
    boolean deleteById(int id);

}

ProductService.java:

package com.gomall.service;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import com.gomall.bean.Product;

public class ProductService implements IProductService {
    public static ArrayList<Product> 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<Product> 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:

package com.gomall.action;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.codehaus.jackson.map.ObjectMapper;

import com.gomall.bean.Product;
import com.gomall.service.IProductService;
import com.gomall.service.ProductService;

@WebServlet("/Product")
public class ProductAction extends HttpServlet {
    private static final long serialVersionUID = 1L;

    public ProductAction() {
        super();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        /*模拟网络延时*/
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        String act = request.getParameter("act");
        IProductService productService = new ProductService();
        /**用于序列化json*/
        ObjectMapper mapper = new ObjectMapper();
        PrintWriter out=response.getWriter();

        if (act.equals("getAll")) {
            String json = mapper.writeValueAsString(productService.getAll());
            out.append(json);
        } else if (act.equals("area")) {
            String callback=request.getParameter("callback");
            out.append(callback+"('"+new Date()+"')");
        } else if (act.equals("getJSONP")) {
            String callback=request.getParameter("callback");
            String json = mapper.writeValueAsString(productService.getAll());
            out.append(callback+"("+json+")");
        } else if (act.equals("getAllCORS")) {
            /**向响应的头部中添加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", "*");
            response.addHeader("Access-Control-Allow-Methods", "GET,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", "*");
            response.addHeader("Access-Control-Allow-Methods", "GET,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, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }
}

客户端跨域调用:

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title>AJAX</title>
        <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
        <style type="text/css">
            @CHARSET "UTF-8";
            * {
                margin: 0;
                padding: 0;
                font-family: microsoft yahei;
                font-size: 14px;
            }

            body {
                padding-top: 20px;
            }

            .main {
                width: 90%;
                margin: 0 auto;
                border: 1px solid #777;
                padding: 20px;
            }

            .main .title {
                font-size: 20px;
                font-weight: normal;
                border-bottom: 1px solid #ccc;
                margin-bottom: 15px;
                padding-bottom: 5px;
                color: blue;
            }

            .main .title span {
                display: inline-block;
                font-size: 20px;
                background: blue;
                color: #fff;
                padding: 0 8px;
                background: blue;
            }

            a {
                color: blue;
                text-decoration: none;
            }

            a:hover {
                color: orangered;
            }

            .tab td,
            .tab,
            .tab th {
                border: 1px solid #777;
                border-collapse: collapse;
            }

            .tab td,
            .tab th {
                line-height: 26px;
                height: 26px;
                padding-left: 5px;
            }

            .abtn {
                display: inline-block;
                height: 20px;
                line-height: 20px;
                background: blue;
                color: #fff;
                padding: 0 5px;
            }

            .btn {
                height: 20px;
                line-height: 20px;
                background: blue;
                color: #fff;
                padding: 0 8px;
                border: 0;
            }

            .abtn:hover,
            .btn:hover {
                background: orangered;
                color: #fff;
            }

            p {
                padding: 5px 0;
            }

            fieldset {
                border: 1px solid #ccc;
                padding: 5px 10px;
            }

            fieldset legend {
                margin-left: 10px;
                font-size: 16px;
            }

            .pic {
                height: 30px;
                width: auto;
            }
            #divFrom{
                display: none;
            }
        </style>
    </head>

    <body>

        <div class="main">
            <h2 class="title">商品管理</h2>
            <table border="1" width="100%" class="tab" id="tabGoods">
                <tr>
                    <th>编号</th>
                    <th>图片</th>
                    <th>商品名</th>
                    <th>价格</th>
                    <th>详细</th>
                    <th>操作</th>
                </tr>
            </table>
            <p style="color: red" id="message"></p>
            <p>
                <a href="#" class="abtn" id="btnSave">添加</a>
                <input type="submit" value="删除选择项" class="btn" />
            </p>
            <div id="divFrom">
            <form id="formPdt">
                <fieldset>
                    <legend>添加商品</legend>
                    <p>
                        <label for="name">
                    名称:
                </label>
                        <input type="text" name="name" id="name" />
                    </p>
                    <p>
                        <label for="price">
                    价格:
                </label>
                        <input type="text" name="price" id="price" />
                    </p>
                    <p>
                        <label for="detail">
                    详细:
                      </label>
                        <textarea id="detail" name="detail" cols="60"></textarea>
                    </p>
                </fieldset>
            </form>
            </div>
        </div>

        <link rel="stylesheet" type="text/css" href="js/artDialog6/ui-dialog.css" />
        <script src="js/jQuery1.11.3/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script>
        <script src="js/artDialog6/dialog-min.js" type="text/javascript" charset="utf-8"></script>

        <!--[if (IE 8)|(IE 9)]>
        <script src="js/jquery.transport.xdr.min.js" type="text/javascript" charset="utf-8"></script>
        <![endif]-->
        <script type="text/javascript">
            var app = {
                url: "http://localhost:8087/JavaScript001/", //提供服务的域名
                add: function() {
                    var d = dialog({
                    title: '添加商品',
                    content: $('#divFrom').html(),
                    okValue: '添加',
                    modal:true,
                    backdropOpacity:0.3,
                    ok: function() {
                        var that = this;
                        $.ajax({
                        type: "post",
                        data: $(".ui-dialog #formPdt").serialize() + "&act=add",
                        success: function(data) {
                            if(data) {
                                app.log("添加成功!");
                                app.loadAll();
                                that.close();
                            } else {
                                app.log("添加失败!");
                            }
                        }
                    });
                    return false;
                    },
                    cancelValue: '关闭',
                    cancel: function() {
                        alert('你点了取消按钮')
                    },
                    onclose:function(){
                        alert("关闭了");
                    }
                });

                d.show();
                },
                del: function() {
                    //closest离当前元素最近的td父元素
                    id = $(this).closest("td").data("id");
                    var that = $(this);
                    $.ajax({
                        type: "get",
                        data: {
                            "id": id,
                            "act": "del"
                        },
                        success: function(data) {
                            if(data) {
                                that.closest("tr").remove();
                                app.log("删除成功!");
                            } else {
                                app.log("删除失败!");
                            }
                        }
                    });
                },
                loadAll: function() {
                    $.ajax({
                        type: "get",
                        data: {
                            "act": "getAllCORS"
                        },
                        success: function(data) {
                            $("#tabGoods tr:gt(0)").remove();
                            $.each(data, function(index, obj) {
                                var tr = $("<tr/>"); //行

                                $("<td/>").html(obj.id).appendTo(tr); //编号

                                var imgTd = $("<td/>");
                                $("<img/>", {
                                    "src": app.url + "images/" + obj.picture,
                                    "class": "pic"
                                }).appendTo(imgTd); //图片
                                imgTd.appendTo(tr);

                                $("<td/>").html(obj.name).appendTo(tr);
                                $("<td/>").html(Math.ceil(obj.price)).appendTo(tr);
                                $("<td/>").html(obj.detail).appendTo(tr);
                                $("<td/>").html("<a href='#' class='abtn del'>删除</a>").data("id", obj.id).appendTo(tr);
                                $("#tabGoods").append(tr);
                            });
                        }
                    });
                },
                init: function() {
                    /*动态绑定删除事件*/
                    $("#tabGoods").on("click", "a.del", {}, app.del);
                    /*绑定添加事件*/
                    $("#btnSave").click(app.add);
                    /*设置全局AJAX默认值*/
                    $.ajaxSetup({
                        dataType: "json",
                        url: app.url + "Product?type=meat-and-filler&format=json",
                        beforeSend: app.ajaxBefore,
                        complete: app.clearMsg,
                        error: function(xhr, textStatus, errorThrown) {
                            app.log("错误" + textStatus + errorThrown);
                        }
                    });
                    this.loadAll();
                },
                clearMsg: function() {
                    this.box.remove();
                },
                ajaxBefore: function() {
                    this.box=dialog({
                        modal:true
                    });
                    this.box.show();
                },
                log: function(msg) {
                    $("#message").html(msg);
                }
            };

            app.init();
        </script>
    </body>

</html>

 

运行结果:

图片 21

删除:

图片 22

5.2、方法

时下新型的版本是4.2与3.x本子有局地不相同,4.x版本的艺术与采用如下:

// 模板名
filename: null,
// 模板语法规则列表
rules: [nativeRule, artRule],
// 是否开启对模板输出语句自动编码功能。为 false 则关闭编码输出功能
// escape 可以防范 XSS 攻击
escape: true,
// 启动模板引擎调试模式。如果为 true: {cache:false, minimize:false, compileDebug:true}
debug: detectNode ? process.env.NODE_ENV !== 'production' : false,
// bail 如果为 true,编译错误与运行时错误都会抛出异常
bail: true,
// 是否开启缓存
cache: true,
// 是否开启压缩。它会运行 htmlMinifier,将页面 HTML、CSS、CSS 进行压缩输出
// 如果模板包含没有闭合的 HTML 标签,请不要打开 minimize,否则可能被 htmlMinifier 修复或过滤
minimize: true,
// 是否编译调试版
compileDebug: false,
// 模板路径转换器
resolveFilename: resolveFilename,
// 子模板编译适配器
include: include,
// HTML 压缩器。仅在 NodeJS 环境下有效
htmlMinifier: htmlMinifier,
// HTML 压缩器配置。参见 https://github.com/kangax/html-minifier
htmlMinifierOptions: {
    collapseWhitespace: true,
    minifyCSS: true,
    minifyJS: true,
    // 运行时自动合并:rules.map(rule => rule.test)
    ignoreCustomFragments: []
},
// 错误事件。仅在 bail 为 false 时生效
onerror: onerror,
// 模板文件加载器
loader: loader,
// 缓存中心适配器(依赖 filename 字段)
caches: caches,
// 模板根目录。如果 filename 字段不是本地路径,则在 root 查找模板
root: '/',
// 默认后缀名。如果没有后缀名,则会自动添加 extname
extname: '.art',
// 忽略的变量。被模板编译器忽略的模板变量列表
ignore: [],
// 导入的模板变量
imports: runtime

方法:

与3.x本子类似,但config方法被注销,越多新查看如下链接

https://aui.github.io/art-template/zh-cn/docs/api.html

方法:

1)、template(id, data)

按照 id 渲染模板。内部会根据document.getElementById(id)查找模板。

只要没有 data 参数,那么将赶回一渲染函数。

2)、template.compile(source, options)

将回来一个渲染函数。演示

3)、template.render(source, options)

将重回渲染结果。

4)、template.helper(name, callback)

加上支援方法,让模板引擎调用自定义的javascript方法。

5)、template.config(name, value)

图片 23

演示代码:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>artTemplate</title>
    </head>
    <body>
        <div id="result">
        </div>
        <script src="js/artTemplate3/template.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/html" id="template1">
            $$if isShow##
              <h2>姓名:$$name##</h2>
              <ul>
                  $$include "template2"##  <!--包含模板2-->
              </ul>
            $$/if##
        </script>

        <script type="text/html" id="template2">
            $$each hobbies as hobby index##
                 <li>
                     $$index+1## $$#hobby##  <!--默认会转义,加#号不转义-->
                 </li>
              $$/each##
        </script>
        <script type="text/javascript">
            var data={
                isShow:true,
                name:"Tom",
                hobbies:["看书","上网","运动","<b>电影</b>","<i>购物</i>"]
            };
            //逻辑语法开始标签
            template.config("openTag","$$");
            //逻辑语法结束标签
            template.config("closeTag","##");
            //不转义
            template.config("escape",false);
            //用数据与模板渲染(render)出结果
            var html=template("template1",data);            
            document.getElementById("result").innerHTML=html;
        </script>
    </body>
</html>

运行结果:

 图片 24

4.x示例:

图片 25图片 26

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title>模板引擎</title>
    </head>

    <body>
        <div id="div1">

        </div>
        <script src="../js/artTemplate4/lib/template-web.js" type="text/javascript" charset="utf-8"></script>

        <script type="text/html" id="t1">
            <div>
                {{if isShow}}
                <h2>{{name}}的爱好列表</h2>
                <table width="50%" border="1">
                    <tr>
                        <th>序号</th>
                        <th>名称</th>
                        <th>操作</th>
                    </tr>
                    {{each hobbies obj i}}
                    <tr>
                        <td>{{i+1}}</td>
                        <td>{{obj}}</td>
                        <td>
                            <a href="#" data-index="{{i}}" class="del">删除</a>
                        </td>
                    </tr>
                    {{/each}}
                </table>
                {{/if}}
            </div>
        </script>

        <script type="text/javascript">
            var data = {
                isShow: true,
                name: "张学友",
                hobbies: ["看书", "<b>上网</b>", "运动", "电影", "购物"]
            };

            var src = document.getElementById("t1");
            var html = template.render(src.innerHTML, data, {
                escape: false
            });
            console.log(html);
            document.getElementById("div1").innerHTML = html;
        </script>
    </body>

</html>

View Code

结果:

图片 27

1.1、优点

不必要插件帮助

美妙的用户体验

增进Web程序的质量

减轻服务器和带宽的承受

3.4.4、Servlet支持CORS

经过改动请求底部门音讯可以完毕Servlet完毕复杂跨域功效,示例如下:

后台:

package com.zhangguo.springmvc08.action;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;

@WebServlet(name = "ProductServlet", value = "/pdt")
public class ProductServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获得所有头部信息
        Enumeration<String> items=request.getHeaderNames();
        String headers="Content-Type,Accept,Origin,XRequestedWith,ContentType,LastModified,Content-Type,ContentType,content-type";
        while(items.hasMoreElements()){
            headers+=","+items.nextElement();
        }
        //设置允许CORS的域名,如果是所有则使用*
        response.addHeader("Access-Control-Allow-Origin", "http://127.0.0.1:8020");
        response.addHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, TRACE, OPTIONS,PUT,DELETE");
        response.addHeader("Access-Control-Request-Headers", "Origin,X-Requested-With,Content-Type,Accept");
        response.addHeader("Access-Control-Allow-Credentials", "true");
        response.getWriter().write("{\"name\":\"Book\"}");
    }

    @Override
    protected void doOptions(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.addHeader("Access-Control-Allow-Headers", "Content-type");
        doGet(req, resp);
    }

    @Override
    protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }

    @Override
    protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

此地在其实使用中有相逢,全部辅助的底部方今或者不或然完全写出来,而又不想在这一层做过多的判定,没涉及,事实上通过request的header可以一向取到Access-Control-Request-Headers,直接把相应的value设置到Access-Control-Allow-Headers即可

前台:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>跨域</title>
    </head>
    <body>
        <script src="../js/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            $.ajax({
                type:"PUT",
                url:"http://localhost:8080/mvc08/pdt",
                contentType:"application/json;charset=utf-8",
                dataType:"json",
                success:function(data){
                    console.log(data);
                }
            });
        </script>
    </body>

</html>

结果:

图片 28

3.4.3、CORSFilter

CORubiconSFilter是Apache官方提供叁个支持COTiguanS跨域的过滤器,详细表明: 
http://tomcat.apache.org/tomcat-7.0-doc/config/filter.html

依赖:

        <!--CORS-->
        <dependency>
            <groupId>com.thetransactioncompany</groupId>
            <artifactId>cors-filter</artifactId>
            <version>2.6</version>
        </dependency>

丰裕过滤器,尽量添加在最前头:

<filter>
        <filter-name>CORS</filter-name>
        <filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>
        <init-param>
            <param-name>cors.allowOrigin</param-name>
            <param-value>http://127.0.0.1:8020</param-value>
        </init-param>
        <init-param>
            <param-name>cors.supportedMethods</param-name>
            <param-value>POST,GET,OPTIONS,DELETE,PUT</param-value>
        </init-param>
        <init-param>
            <param-name>cors.supportedHeaders</param-name>
            <param-value>Content-Type,Accept,Origin,XRequestedWith,ContentType,LastModified</param-value>
        </init-param>
        <init-param>
            <param-name>cors.exposedHeaders</param-name>
            <param-value>SetCookie</param-value>
        </init-param>
        <init-param>
            <param-name>cors.supportsCredentials</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>

    <filter-mapping>
        <filter-name>CORS</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

只要运用了Spring MVC,请开启Spring对OPTIONS的支撑:

<init-param>
<param-name>dispatchOptionsRequest</param-name>
<param-value>true</param-value>
</init-param>

客户端:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>跨域</title>
    </head>
    <body>
        <script src="../js/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            $.ajax({
                type:"PUT",
                url:"http://localhost:8080/mvc08/u",
                contentType:"application/json;charset=utf-8",
                dataType:"json",
                success:function(data){
                    console.log(data);
                }
            });
        </script>
    </body>

</html>

服务器:

package com.zhangguo.springmvc08.action;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;

@WebServlet(name = "UserServlet", value = "/u")
public class UserServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.getWriter().write("{\"name\":\"Book\"}");
    }

    @Override
    protected void doOptions(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }

    @Override
    protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }

    @Override
    protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

结果:

图片 29

web.xml

图片 30图片 31

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

    <!--welcome pages-->
    <welcome-file-list>
        <welcome-file>users/tom</welcome-file>
    </welcome-file-list>

    <!--配置springmvc DispatcherServlet(中心控制器)-->
    <servlet>
        <servlet-name>springMVC</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <!--Sources标注的文件夹下需要新建一个spring文件夹-->
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath*:spring/spring-mvc.xml</param-value>
        </init-param>
        <init-param>
            <param-name>dispatchOptionsRequest</param-name>
            <param-value>true</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
        <async-supported>true</async-supported>
    </servlet>
    <servlet-mapping>
        <servlet-name>springMVC</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <filter>
        <filter-name>CORS</filter-name>
        <filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>
        <init-param>
            <param-name>cors.allowOrigin</param-name>
            <param-value>http://127.0.0.1:8020</param-value>
        </init-param>
        <init-param>
            <param-name>cors.supportedMethods</param-name>
            <param-value>POST,GET,OPTIONS,DELETE,PUT</param-value>
        </init-param>
        <init-param>
            <param-name>cors.supportedHeaders</param-name>
            <param-value>Content-Type,Accept,Origin,XRequestedWith,ContentType,LastModified</param-value>
        </init-param>
        <init-param>
            <param-name>cors.exposedHeaders</param-name>
            <param-value>SetCookie</param-value>
        </init-param>
        <init-param>
            <param-name>cors.supportsCredentials</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>

    <filter-mapping>
        <filter-name>CORS</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

View Code

3.3、jQuery使用JSONP跨域

在jQuery中放置了完成JSONP跨域的功力,假若内定为json类型,则会把获得到的数量作为二个JavaScript对象来分析,并且把营造好的对象作为结果回到。为了促成那几个目标,他首先尝试使用JSON.parse()。假设浏览器不扶助,则动用一个函数来打造。JSON数据是一种能很有益于通过JavaScript解析的结构化数据。假若得到的数据文件存放在长途服务器上(域名差别,也等于跨域获取数据),则需求接纳jsonp类型。使用这种类型的话,会制造2个查询字符串参数
callback=?
,这几个参数会加在请求的UCR-VL前边。服务器端应当在JSON数据前增加回调函数名,以便形成八个卓有作用的JSONP请求。要是要内定回调函数的参数名来顶替暗许的callback,可以透过安装$.ajax()的jsonp参数。

页面脚本:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>6.4.9、跨域AJAX请求</title>
</head>
<body>
    <h2>6.4.9、跨域AJAX请求</h2>
    <h2 id="message"></h2>
    <button type="button" id="btnAjax">ajax请求</button>
    <script type="text/javascript" src="js/jQuery/jquery.min.js"></script>
    <script type="text/javascript">
        $("#btnAjax").click(function() {
            $.get("http://localhost:12833/Action/FindUserById.ashx?callback=?",{"id":1001},function(data){
                log(data);
            },"jsonp");
        });

        function log(msg) {
            $("#message")[0].innerHTML += msg + "<br/>";
        }
    </script>
</body>
</html>

服务器一般处理程序:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace jQuery601_DotNet.Action
{
    /// <summary>
    /// FindUserById 的摘要说明
    /// </summary>
    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";
            }
            String callback = context.Request["callback"];
            context.Response.Write(callback+"('"+name+"')");
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}

运营结果:

图片 32

图片 33

服务器Servlet: 

package com.gomall.action;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.codehaus.jackson.map.ObjectMapper;

import com.gomall.service.IProductService;
import com.gomall.service.ProductService;

@WebServlet("/Product")
public class Product extends HttpServlet {
    private static final long serialVersionUID = 1L;

    public Product() {
        super();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        String act = request.getParameter("act");
        IProductService productService = new ProductService();
        ObjectMapper mapper = new ObjectMapper();
        PrintWriter out=response.getWriter();

        if (act.equals("getAll")) {
            String json = mapper.writeValueAsString(productService.getAll());
            out.append(json);
        } else if (act.equals("area")) {
            String callback=request.getParameter("callback");
            out.append(callback+"('"+new Date()+"')");
        } else if (act.equals("getJSONP")) {
            String callback=request.getParameter("callback");
            String json = mapper.writeValueAsString(productService.getAll());
            out.append(callback+"("+json+")");
        } 
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }
}

客户端:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>AJAX</title>
    </head>
    <body>
        <script src="js/jQuery1.11.3/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            $.get("http://localhost:8087/JavaScript001/Product?callback=?",{act:"getJSONP"},function(data){
                $.each(data,function(index,obj){
                    $("<p/>").html(obj.name).appendTo("body");
                });
            },"jsonp");
        </script>
    </body>
</html>

运作结果:

图片 34

图片 35

在jQuery中一经使用JSONP只必要将回来数据类型设置为jsonp就可以了,但是那种方法只帮忙get请求,不协助post请求;请求是一路的;服务器再次回到数据要拍卖,要添加回调函数,麻烦。

3.5、小结

本来除了包容老浏览器的jsonp跨域与HTML5中的CO路虎极光S跨域还有许多其他方法如使用iframe和location.hash、window.name已毕的跨域数据传输、使用HTML5
postMessage、利用flash等艺术。个人觉得CO中华VS应该才是鹏程重大的跨域接纳,其余的方式都只是hack。

2.六 、应用延迟对象

前面的示范中我们都是使用jQuery
ajax重回的deferred对象,其实大家也可以在自定义的代码中运用deferred对象,恰当的运用deferred对象或以优雅的缓解许多题材。

示例:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>延迟对象(deferred)</title>
    </head>
    <body>
        <script src="js/jQuery1.11.3/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            var myTask=function(){
                //通过jQuery创建一个延迟对象
                var def=$.Deferred();
                setTimeout(function(){
                    //随机产生一个整数,如果是偶数
                    var n=Math.round(Math.random()*100);
                    if(n%2==0)
                    {
                        console.log("一个耗时的操作终于完成了,n="+n);
                        def.resolve();   //任务成功完成
                    }else{
                        console.log("一个耗时的操作失败,n="+n);
                        def.reject();  //拒绝,失败
                    }
                },3000);
                 //返回延迟对象,防止中间修改
                return def.promise();
            }

            /*当方法myTask执行完成后,添加回调方法*/
            $.when(myTask()).done(function(){
                console.log("执行成功");
            }).fail(function(){
                console.log("执行失败");
            });
        </script>
    </body>
</html>

失败时:

图片 36

成功时:

图片 37

promise()在本来的deferred对象上回来另一个deferred对象,后者只开放与转移执行情状毫不相关的不二法门(比如done()方法和fail()方法),屏蔽与转移执行意况有关的法子(比如resolve()方法和reject()方法),从而使得执市场价格形不可以被改动。

示例2:

图片 38图片 39

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title>Deferred</title>
    </head>

    <body>
        <script src="../js/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            var task = function() {
                //创建延迟对象
                var def = $.Deferred();
                //随机产生一个数
                var n = Math.round(Math.random() * 10000);

                setTimeout(function() {
                    if(n % 2 == 0) {
                        console.log("成功,耗时的任务完成了");
                        def.resolve(n); //通知成功
                    } else {
                        console.log("失败,耗时的任务完成了");
                        def.reject(n); //通知失败
                    }
                }, n);

                return def.promise();
            };

            $.when(task()).done(function(data) {
                console.log(data);
            }).fail(function(data) {
                console.log(data);
            });
        </script>
    </body>

</html>

View Code

结果2:

图片 40

3.4.5、Spring MVC4.2+ CORS注解

Spring MVC4.2 及以上增加了对CO卡宴S的协理

三个采纳只怕会有多少个 CORAV4S 配置,并且可以安装每种 CORubiconS
配置针对二个接口或一星罗棋布接口可能对全体接口生效。

对第三种情状,如若想要对某一接口配置 CO科雷傲S,能够在艺术上添加 CrossOrigin
申明:

@CrossOrigin(origins = {"http://localhost:9000", "null"})
@RequestMapping(value = "/test", method = RequestMethod.GET)
public String greetings() {
    return "{\"project\":\"just a test\"}";
}

第①种处境,即便想对一系列接口添加 COXC60S
配置,可以在类上添加注明,对该类表明全部接口都有效:

@CrossOrigin(origins = {"http://localhost:8080", "null"})
@RestController
public class HomeController{
}

其二种情景,添加全局配置,则要求丰盛两个配置类:

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("http://localhost:9000", "null")
                .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE")
                .maxAge(3600)
                .allowCredentials(true);
    }
}

可以通过抬高 Filter 的点子,配置 CO逍客S 规则,并手动钦点对怎么着接口有效。

@Bean

public FilterRegistrationBean corsFilter() {
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    CorsConfiguration config = new CorsConfiguration();
    config.setAllowCredentials(true);    config.addAllowedOrigin("http://localhost:9000");
    config.addAllowedOrigin("null");
    config.addAllowedHeader("*");
    config.addAllowedMethod("*");
    source.registerCorsConfiguration("/**", config); // CORS 配置对所有接口都有效
    FilterRegistrationBean bean = newFilterRegistrationBean(new CorsFilter(source));
    bean.setOrder(0);
    return bean;
}

也可以修改配置文件:

    <mvc:cors>
        <mvc:mapping path="/**"
                     allowed-origins="http://127.0.0.1:8020"
                     allowed-methods="POST,GET, OPTIONS,DELETE,PUT"
                     allowed-headers="Content-Type,ContentType,Access-Control-Allow-Headers, Authorization, X-Requested-With"
                     allow-credentials="true"/>
    </mvc:cors>

员工管理的跨域综合示范

后台REST服务:

图片 41图片 42

package com.zhangguo.springmvc08.controller;

import com.zhangguo.springmvc08.entity.User;
import com.zhangguo.springmvc08.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

@RestController
@RequestMapping(path = "/emps")
public class EmpController extends BaseController {

    @Autowired
    UserService userService;

    @RequestMapping(path = "")
    public AjaxState getAllEmps(HttpServletRequest request, HttpServletResponse response) {
        List<User> users=userService.queryAllUsers();
        boolean result=users!=null;
        return new AjaxState(result?"success":"error",users,result?"获得数据成功!":"获得数据失败!");
    }

    @RequestMapping(path = "/{id}", method = RequestMethod.GET)
    public AjaxState getEmpById(@PathVariable int id) {
        User user=userService.getUserById(id);
        boolean result=user!=null;
        return new AjaxState(result?"success":"error",user,result?"获得数据成功!":"获得数据失败!");
    }

    @RequestMapping(path = "", method = RequestMethod.POST)
    public AjaxState addEmp(@RequestBody User user) {
        boolean result=userService.addUser(user);
        return new AjaxState(result?"success":"error",user,result?"添加成功!":"添加失败");
    }

    @RequestMapping(path = "", method = RequestMethod.PUT)
    public AjaxState updateEmp(@RequestBody User user) {
        boolean result=userService.editUser(user);
        return new AjaxState(result?"success":"error",user,result?"修改成功!":"修改失败");
    }

    @RequestMapping(path = "/{id}", method = RequestMethod.DELETE)
    public AjaxState deleteEmpById(@PathVariable int id) {
        Boolean result=userService.deleteUser(id);
        return new AjaxState(result?"success":"error",id,result?"删除成功!":"删除失败");
    }

}

class  AjaxState{
    public String state;
    public Object data;
    public String message;

    public AjaxState(String state, Object data, String message) {
        this.state = state;
        this.data = data;
        this.message = message;
    }

    public AjaxState(){}
}

View Code

Spring配置文件:

图片 43图片 44

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.3.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd">

    <!--启用spring的一些annotation -->
    <context:annotation-config/>

    <!-- 自动扫描该包,使SpringMVC认为包下用了@controller注解的类是控制器 -->
    <context:component-scan base-package="com.zhangguo.springmvc08">
    </context:component-scan>

    <!--HandlerMapping 无需配置,springmvc可以默认启动-->

    <!--静态资源映射-->
    <mvc:default-servlet-handler/>
    <!--如果发现是静态资源的请求,就将该请求转由Web应用服务器默认的Servlet处理,如果不是静态资源的请求,才由DispatcherServlet继续处-->
    <!--本项目把静态资源放在了WEB-INF的statics目录下,资源映射如下-->
    <!--<mvc:resources mapping="/css/**" location="/WEB-INF/statics/css/"/>-->
    <!--<mvc:resources mapping="/js/**" location="/WEB-INF/statics/js/"/>-->
    <!--<mvc:resources mapping="/image/**" location="/WEB-INF/statics/image/"/>-->

    <!--但是项目部署到linux下发现WEB-INF的静态资源会出现无法解析的情况,但是本地tomcat访问正常,因此建议还是直接把静态资源放在webapp的statics下,映射配置如下-->
    <!--<mvc:resources mapping="/css/**" location="/statics/css/"/>-->
    <!--<mvc:resources mapping="/js/**" location="/statics/js/"/>-->
    <!--<mvc:resources mapping="/image/**" location="/statics"/>-->


    <mvc:cors>
        <mvc:mapping path="/**"
                     allowed-origins="http://127.0.0.1:8020"
                     allowed-methods="POST,GET, OPTIONS,DELETE,PUT"
                     allowed-headers="Content-Type,ContentType,Access-Control-Allow-Headers, Authorization, X-Requested-With"
                     allow-credentials="true"/>
    </mvc:cors>

    <!-- 配置注解驱动 可以将request参数与绑定到controller参数上 -->
    <mvc:annotation-driven>
        <mvc:message-converters register-defaults="true">
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <constructor-arg value="UTF-8"/>
            </bean>
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="objectMapper">
                    <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
                        <property name="failOnEmptyBeans" value="false"/>
                    </bean>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

    <!-- 对模型视图名称的解析,即在模型视图名称添加前后缀(如果最后一个还是表示文件夹,则最后的斜杠不要漏了) 使用JSP-->
    <!-- 默认的视图解析器 在上边的解析错误时使用 (默认使用html)- -->
    <bean id="defaultViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
        <property name="prefix" value="/WEB-INF/views/"/><!--设置JSP文件的目录位置-->
        <property name="suffix" value=".jsp"/>
    </bean>

    <!-- springmvc文件上传需要配置的节点-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="20971500"/>
        <property name="defaultEncoding" value="UTF-8"/>
        <property name="resolveLazily" value="true"/>
    </bean>
</beans>

View Code

前端:

图片 45图片 46

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8"/>
    <title>员工管理</title>
</head>
<body>
<h2>员工管理</h2>
<table border="1" width="100%" id="tabEmps">
    <tr>
        <th>编号</th>
        <th>姓名</th>
        <th>生日</th>
        <th>地址</th>
        <th>电话</th>
        <th>操作</th>
    </tr>
</table>
<p class="loading" style="display: none;">
    <img src="img/loading.gif" align="absmiddle">努力加载中...
</p>
<form id="formEmps">
    <fieldset>
        <legend>用户信息</legend>
        <p>
            <label for="name">姓名:</label>
            <input name="name" id="name" type="text" required="required" maxlength="32"/>
        </p>
        <p>
            <label for="birthday">生日:</label>
            <input name="birthday" id="birthday" type="date" required="required" maxlength="8"/>
        </p>
        <p>
            <label for="address">地址:</label>
            <input name="address" id="address" type="text" required="required" maxlength="128"/>
        </p>
        <p>
            <label for="phone">电话:</label>
            <input name="phone" id="phone" type="text" required="required" maxlength="11"/>
        </p>
        <p>
            <input id="id" type="hidden" name="id" value=""/>
            <button type="button" id="btnSubmit">保存</button>
        </p>
    </fieldset>
</form>
<p class="message">
</p>
<script src="../js/jquery-1.11.3.min.js"></script>
<script>
    var app = {
        url: "http://localhost:8080/mvc08/emps",
        init: function () {
            $("#btnSubmit").click(app.save);
            $("#tabEmps").on("click", ".del", app.delete);
            $("#tabEmps").on("click", ".edit", app.edit);
            this.binddata();
        },
        ajax: function (actionType, callback, path, data) {
            $.ajax({
                url: app.url + (path || ""),
                contentType: "application/json;charset=utf-8",
                data: JSON.stringify(data) || "{}",
                type: actionType || "get",
                dataType: "json",
                success: function (data) {
                    if (data && data.state == "success") {
                        app.info(data.message);
                    } else if (data && data.state == "error") {
                        app.info(data.message);
                    } else {
                        app.info(data);
                    }
                    if (callback) {
                        callback(data);
                    }
                },
                error: function (XMLHttpRequest, textStatus, errorThrown) {
                    app.info(textStatus + errorThrown);
                },
                beforeSend: function () {
                    $(".loading").show(200);
                }
                ,
                complete: function () {
                    $(".loading").hide(200);
                }
            })
            ;
        },
        binddata: function () {
            $("#tabEmps tr:gt(0)").remove();
            this.ajax("get", function (data) {
                $.each(data.data, function (index, emp) {
                    var tr = $("<tr/>").data("emp", emp).appendTo("#tabEmps");
                    $("<td/>").text(emp.id).appendTo(tr);
                    $("<td/>").text(emp.name).appendTo(tr);
                    $("<td/>").text(emp.birthday).appendTo(tr);
                    $("<td/>").text(emp.address).appendTo(tr);
                    $("<td/>").text(emp.phone).appendTo(tr);
                    $("<td/>").html("<a class='del' href='#'>删除</a> | <a class='edit' href='#'>编辑</a>").appendTo(tr);
                });
            });
        },
        getEmp: function () {
            return {
                "id": $("#id").val(),
                "name": $("#name").val(),
                "birthday": $("#birthday").val(),
                "address": $("#address").val(),
                "phone": $("#phone").val()
            };
        },
        save: function () {
            var emp = app.getEmp();
            if (emp.id) {
                $("#id").val("");
                app.update(emp);
            } else {
                app.add(emp);
            }
        },
        add: function (emp) {
            app.ajax("POST", function (data) {
                app.binddata();
            }, "", emp);
        },
        update: function (emp) {
            app.ajax("Put", function (data) {
                app.binddata();
            }, "", emp);
        },
        delete: function () {
            if (confirm("删除吗?")) {
                var tr = $(this).closest("tr");
                var emp = tr.data("emp");
                app.ajax("DELETE", function (data) {
                    tr.remove();
                }, "/" + emp.id);
            }
        },
        edit:function(){
            var emp = $(this).closest("tr").data("emp");
            $("#id").val(emp.id);
            $("#name").val(emp.name);
            $("#birthday").val(emp.birthday);
            $("#address").val(emp.address);
            $("#phone").val(emp.phone);
        },
        info: function (msg) {
            $(".message")[0].innerHTML += msg + "<br/>";
        }
    };

    app.init();
</script>
</body>
</html>

View Code

运营结果:

图片 47

 其它跨域示例:

.Net服务器一般处理程序代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace jQuery601_DotNet.Action
{
    /// <summary>
    /// FindUserById 的摘要说明
    /// </summary>
    public class FindUserById : IHttpHandler
    {

        public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "text/plain";
            context.Response.Headers.Add("Access-Control-Allow-Origin","*");
            context.Response.Headers.Add("Access-Control-Allow-Methods", "GET,POST");
            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;
            }
        }
    }
}

 客户端脚本:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>6.4.9、跨域AJAX请求</title>
</head>
<body>
    <h2>6.4.9、跨域AJAX请求</h2>
    <h2 id="message"></h2>
    <button type="button" id="btnAjax">ajax请求</button>
    <script type="text/javascript" src="js/jQuery/jquery.min.js"></script>
    <script type="text/javascript">
        $("#btnAjax").click(function() {
            $.get("http://localhost:12833/Action/FindUserById.ashx",{"id":1001},function(data){
                log(data);
            },"text");
        });

        function log(msg) {
            $("#message")[0].innerHTML += msg + "<br/>";
        }
    </script>
</body>
</html>

运维结果:

图片 48

从上图可以见到完结跨域且为异步请求。

Java Servlet后台脚本:

package com.gomall.action;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.codehaus.jackson.map.ObjectMapper;

import com.gomall.service.IProductService;
import com.gomall.service.ProductService;

@WebServlet("/Product")
public class Product extends HttpServlet {
    private static final long serialVersionUID = 1L;

    public Product() {
        super();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        String act = request.getParameter("act");
        IProductService productService = new ProductService();
        ObjectMapper mapper = new ObjectMapper();
        PrintWriter out=response.getWriter();

        if (act.equals("getAll")) {
            String json = mapper.writeValueAsString(productService.getAll());
            out.append(json);
        } else if (act.equals("area")) {
            String callback=request.getParameter("callback");
            out.append(callback+"('"+new Date()+"')");
        } else if (act.equals("getJSONP")) {
            String callback=request.getParameter("callback");
            String json = mapper.writeValueAsString(productService.getAll());
            out.append(callback+"("+json+")");
        } else if (act.equals("getAllCORS")) {
            /**向响应的头部中添加内容*/
            response.addHeader("Access-Control-Allow-Origin", "*");
            response.addHeader("Access-Control-Allow-Methods", "GET,POST");

            String json = mapper.writeValueAsString(productService.getAll());
            out.append(json);
        } 
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }
}

客户端代码:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>AJAX</title>
    </head>
    <body>
        <script src="js/jQuery1.11.3/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            $.get("http://localhost:8087/JavaScript001/Product?act=getAllCORS",function(data){
                alert(data);
            });
        </script>
    </body>
</html>

运行结果:

 图片 49

 图片 50

⑤ 、模板引擎

在AJAX示例中javascript中有恢宏的html字符串,html中有局地像onclick样的javascript,那样javascript中有html,html中有javascript,代码的偶合度很高,不便于修改与维护,使用模板引擎能够消除难题。

模板引擎(那里特指用于Web开发的模版引擎)是为了使用户界面与工作数据(内容)分离而发生的,它可以变动特定格式的文档,用于网站的模板引擎就会扭转三个正规的HTML文档。前后端都有模板引擎,比如T肆 、Free马克尔、Velocity,那里根本讲前端模板引擎:

图片 51

上图是普遍的局部前端模板引擎,速度相对快的是artTemplate,与artDialog是同二个小编,当然2个好的模版引擎不仅是速度还有很多方面都重点。

源码与援救: https://github.com/aui/artTemplate

二 、延迟对象(Deferred)

deferred对象就是jQuery1.5版之后新扩大的回调函数消除方案。

1.2、缺点

浏览器对XMLHttpRequest对象的协理度相差,差不离全数浏览器将来都协理

破坏浏览器“前进”、“后退”按钮的健康职能,可以通过不难的插件弥补

对寻找引擎的支撑不足

图片 52

2.2、deferred.done

$.ajax()操作已毕后,若是采用的是自愧不如1.5.0本子的jQuery,重回的是XH陆风X8对象,你无法展开链式操作;尽管过量1.5版,再次回到的是deferred对象,可以拓展链式操作。

图片 53

 

当延迟成功时调用多少个函数可能数组函数,功能与原success类似。

语法:deferred.done(doneCallbacks[,doneCallbacks]) 

返回值:Deferred Object

该参数可以是三个函数或二个函数的数组。当延迟成功时,doneCallbacks被调用。回调执行是依据他们添加的逐条。一旦deferred.done()重回延迟对象,延迟对象的别样方法也得以链接到了那边,包罗伸张.done()方法。当延迟消除,doneCallbacks执行使用参数提须要resolve或 resolveWith方法依据添加的顺序调用。

以身作则代码:

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title>延迟对象(deferred)</title>
    </head>

    <body>
        <script src="js/jQuery1.11.3/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            console.log("使用方法一");
            $.get("student.json", "json").done(function(stu) {
                console.log(stu.id);
            }).done(function(stu) {
                console.log(stu.name);
            });

            console.log("使用方法二");
            $.get("student.json", "json").done(function(stu) {
                console.log(stu.id);
            }, function(stu) {
                console.log(stu.name);
            });
        </script>
    </body>

</html>

运作结果:

图片 54

四、弹出层

后面AJAX示例中添加效果一旦身处多个弹出层中布局会更为严峻一些,像登录,提醒新闻常常会必要弹出层。

广大的弹出层有:FancyBox,LightBox,colorBox,artDialog,BlockUI,Layer等,那里介绍腾讯开源的artDialog,轻量,实用。

图片 55

artDialog是三个企划得要命漂亮纷呈的对话框组件,小巧身材却具有充裕的接口与美好的外观。

特色是自适应内容、优雅的接口、细致的体会、跨平台包容、轻量实用。

品类源码: https://github.com/aui/artDialog

扶持音讯: http://img0.zz91.com/huanbao/mblog/artDialog-5.0.4

文档与示范: http://aui.github.io/artDialog/doc/index.html

AngularJS 版本: https://github.com/aui/angular-popups

使用方法:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>artDialog</title>
    </head>
    <body>
        <button onclick="btn_dialog()">
            弹出框
        </button>
        <button onclick="btn_loading()">
            加载中
        </button>
        <script src="js/jQuery1.11.3/jquery-1.11.3.js" type="text/javascript" charset="utf-8"></script>
        <script src="js/artDialog6/dialog-min.js" type="text/javascript" charset="utf-8"></script>
        <link rel="stylesheet" type="text/css" href="js/artDialog6/ui-dialog.css" />
        <script type="text/javascript">
            function btn_dialog() {
                var d = dialog({
                    title: '消息',
                    content: '风吹起的青色衣衫,夕阳里的温暖容颜,你比以前更加美丽,像盛开的花<br>——许巍《难忘的一天》',
                    okValue: '确 定',
                    ok: function() {
                        var that = this;
                        setTimeout(function() {
                            that.title('提交中..');
                        }, 2000);
                        return false;
                    },
                    cancelValue: '取消',
                    cancel: function() {
                        alert('你点了取消按钮')
                    }
                });

                d.show();
            }

            function btn_loading(){
                dialog({
                    modal:true
                }).show();
            }
        </script>
    </body>

</html>

运作结果:

图片 56

图片 57

属性:

 // 对齐方式
    //align: 'bottom left',

    // 是否固定定位
    //fixed: false,

    // 对话框叠加高度值(重要:此值不能超过浏览器最大限制)
    //zIndex: 1024,

    // 设置遮罩背景颜色
    backdropBackground: '#000',

    // 设置遮罩透明度
    backdropOpacity: 0.7,

    // 消息内容
    content: 'Loading..',

    // 标题
    title: '',

    // 对话框状态栏区域 HTML 代码
    statusbar: '',

    // 自定义按钮
    button: null,

    // 确定按钮回调函数
    ok: null,

    // 取消按钮回调函数
    cancel: null,

    // 确定按钮文本
    okValue: 'ok',

    // 取消按钮文本
    cancelValue: 'cancel',

    cancelDisplay: true,

    // 内容宽度
    width: '',

    // 内容高度
    height: '',

    // 内容与边界填充距离
    padding: '',

    // 对话框自定义 className
    skin: '',

    // 是否支持快捷关闭(点击遮罩层自动关闭)
    quickClose: false,

    // css 文件路径,留空则不会使用 js 自动加载样式
    // 注意:css 只允许加载一个
    cssUri: '../css/ui-dialog.css',

事件:

/**
     * 显示对话框
     * @name artDialog.prototype.show
     * @param   {HTMLElement Object, Event Object}  指定位置(可选)
     */

    /**
     * 显示对话框(模态)
     * @name artDialog.prototype.showModal
     * @param   {HTMLElement Object, Event Object}  指定位置(可选)
     */

    /**
     * 关闭对话框
     * @name artDialog.prototype.close
     * @param   {String, Number}    返回值,可被 onclose 事件收取(可选)
     */

    /**
     * 销毁对话框
     * @name artDialog.prototype.remove
     */

    /**
     * 重置对话框位置
     * @name artDialog.prototype.reset
     */

    /**
     * 让对话框聚焦(同时置顶)
     * @name artDialog.prototype.focus
     */

    /**
     * 让对话框失焦(同时置顶)
     * @name artDialog.prototype.blur
     */

    /**
     * 添加事件
     * @param   {String}    事件类型
     * @param   {Function}  监听函数
     * @name artDialog.prototype.addEventListener
     */

    /**
     * 删除事件
     * @param   {String}    事件类型
     * @param   {Function}  监听函数
     * @name artDialog.prototype.removeEventListener
     */

    /**
     * 对话框显示事件,在 show()、showModal() 执行
     * @name artDialog.prototype.onshow
     * @event
     */

    /**
     * 关闭事件,在 close() 执行
     * @name artDialog.prototype.onclose
     * @event
     */

    /**
     * 销毁前事件,在 remove() 前执行
     * @name artDialog.prototype.onbeforeremove
     * @event
     */

    /**
     * 销毁事件,在 remove() 执行
     * @name artDialog.prototype.onremove
     * @event
     */

    /**
     * 重置事件,在 reset() 执行
     * @name artDialog.prototype.onreset
     * @event
     */

    /**
     * 焦点事件,在 foucs() 执行
     * @name artDialog.prototype.onfocus
     * @event
     */

    /**
     * 失焦事件,在 blur() 执行
     * @name artDialog.prototype.onblur
     * @event
     */

该插件使用相比较简单,可以看示例与源代码。

七、视频

http://www.bilibili.com/video/av17173253/

https://www.bilibili.com/video/av16991874/

3.4.六 、IE8达成COLacrosseS跨域的标题

a)、即便以为每一回需求修改HTTP尾部相比麻烦,在java中可以行使过滤器,.Net可以行使Module或HttpHandler全局注册(注册到Web.Config中,计划时还须要专注)。

b)、借使急需考虑IE8已毕COCR-VS则要插件接济,因为IE8并从未完全帮衬CO本田CR-VS。

插件名称:javascript-jquery-transport-xdr

github: https://github.com/gfdev/javascript-jquery-transport-xdr

以身作则代码:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>AJAX</title>
    </head>
    <body>
        <script src="js/jQuery1.11.3/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script>
        <!--[if (IE 8)|(IE 9)]>
        <script src="js/jquery.transport.xdr.min.js" type="text/javascript" charset="utf-8"></script>
        <![endif]-->

        <script type="text/javascript">
            $.get("http://localhost:8087/JavaScript001/Product?act=getAllCORS&type=meat-and-filler&format=json",{},function(data){
                alert(data);
            },"json");
        </script>
    </body>
</html>

运行结果:

图片 58

2.4、deferred.always

语法:deferred.always(alwaysCallbacks,[alwaysCallbacks])

返回值:Deferred Object

当递延对象是消除(成功,
resolved)或拒绝(失利,rejected)时被调用添加处理程序,与回调方法complete类似。

示例:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>延迟对象(deferred)</title>
    </head>
    <body>
        <script src="js/jQuery1.11.3/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            $.get("student.j", "json").done(function(stu) {
                console.log(stu.name);
            }).fail(function(data, status, errorThrown){
                console.log("data:"+data+",status:"+status+",errorThrown:"+errorThrown);
            }).always(function(data, textStatus){
                console.log("ajax执行完成,完成状态:"+textStatus);
            });
        </script>
    </body>
</html>

运转结果

成功时:

 图片 59

失败时:

图片 60

相关文章