zoukankan      html  css  js  c++  java
  • 30分钟全面解析-图解AJAX原理

    先上原理图:

    高清无码图在这里:点我查看大图!!!

    背景:

    1.传统的Web网站,提交表单,需要重新加载整个页面。

    2.如果服务器长时间未能返回Response,则客户端将会无响应,用户体验很差。

    3.服务端返回Response后,浏览器需要加载整个页面,对浏览器的负担也是很大的。

    4.浏览器提交表单后,发送的数据量大,造成网络的性能问题。

    问题:

    1.如何改进?

    2.AJAX是什么?

    3.有什么优势?

    4.有什么缺点?

    一、什么是 AJAX 

    1.为什么需要AJAX

    当需要从服务器获取数据,并刷新页面的操作,如果不采用AJAX,则需要用提交整个表单的方式,当提交表单时,发送请求给服务器,页面需要等待服务器发送完response后,页面才能恢复操作。

    2.AJAX的概念:

    1.AJAX = 异步 JavaScript 和 XML。

    2.AJAX 是一种用于创建快速动态网页的技术。

    3.通过在后台与服务器进行少量数据交换,可以使网页实现异步更新。

    4.可以在不重新加载整个网页的情况下,对网页的某部分进行更新。

    3.什么叫异步

    当前页面发送一个请求给服务器,当前页面不需要等待服务器响应才能操作网页。发送完请求之后,当前页面可以继续浏览,操作。

    4.什么叫局部刷新

    我们可以用两种方式来实现部分刷新。

    1. iframe页面重载的方式。

    这种方式虽然实现了部分刷新,但是是页面的重载,所以也会带来性能上的问题。

    Step1.在页面中定义一个Iframe

    <iframe id="indexFrame" name="index" width="1000" height="800" 
                    frameborder="0" marginwidth="0" marginheight="0" scrolling="yes" style="margin-top:100px;"></iframe>

    Step2.设置Iframe的src

    var indexFrame = document.getElementById("indexFrame");
    indexFrame.src = "introduction.php";

    Step3.添加一个button的点击事件,当点击这个button时,重新设置Iframe的src,实现iframe里面的页面刷新。Iframe外面的内容不刷新。

    <button id="room" onclick='IndexClick("room")'>Click Me!</button>
    function IndexClick(moduleKey) {
        var indexFrame = document.getElementById("indexFrame");
        if(indexFrame == null)
        {
                indexFrame = parent.document.getElementById("indexFrame");
        }
        var url = "introduction.php";
        switch (moduleKey) {
            case "introduction":
                url = "introduction.php";
                break;
            case "room":
                url = "room.php";
                break;
            default:
                {
                }
        }
        indexFrame.src = url;
    }

    通过这种方式我们可以实现一个导航栏的功能:

      

      

      2.AJAX方式

        Step1.JavaScrpit发送异步请求

        Step2.服务端查询数据库,返回数据

        Step3.服务端返回Response

        Step4.客户端根据返回的Response,来用JavaScript操作DOM。

      看下面的例子:

      

      当我们切换DropDownList中的Item时,JavaScript发送异步请求给Server端,Server端返回数据,然后JavaScript将数据解析出来,拼接了一个Table,将Table呈现在页面上。

    二、提交Form表单的原理

    1.代码

    客户端代码:

    <form id="form1" action="Test.ashx" method="get">
                您的姓名1:<input type="text" name="fname" size="20" />
                <input type="submit" name="submit" value="Sumbit">
     </form>
    

    服务端代码:

    public void ProcessRequest (HttpContext context)
    {
            //Delay
            for (int i = 0; i < 2; i++)
            {
                System.Threading.Thread.Sleep(1000);
            }
     
             //从Requset.Form中获取fname的值。使用Form获取请求的键值对的值的前提条件是HTTP request Content-Type 值必须是"application/x-www-form-urlencoded" 或 "multipart/form-data".
            string fname = context.Request["fname"];
    
            context.Response.ContentType = "text/plain";
    	//将字符串写入 HTTP 响应输出流。
            context.Response.Write("Hello World " + fname);
     }
     
    

    2.将代码部署到IIS

    3.打开站点:

    http://localhost:8003/Test.html

    4.输入“Jackson0714”然后点击Sumbit按钮

    页面会重新刷新,显示"Hello World Jackson0714"

    5.提交Form表单后,页面发送请求和服务端返回响应的流程

     

    6.通过抓包,我们可以得到HTTP Headers

    浏览器发送HTTP给服务端,采取的协议是HTTP协议。

    在传输过程中,我们可以看下HTTP Headers。

    三、AJAX提交请求和服务响应的原理

    1.代码

    客户端HTML代码:

    <!DOCTYPE html>
    
    <html lang="en" xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta charset="utf-8" />
        <title></title>
        <script type="text/javascript" src="Ajax.js"></script>
    
    </head>
    <body>
        <div id="Test" style="background-color:#40eeee">
            您的姓名2:<input type="text" id="testGetName" size="20" />
            <button type="button" onclick="testGet();">Ajax Get请求</button>
        </div>
            
        <div id="Test" style="background-color:#ff6a00">
            您的姓名3:<input type="text" id="testPostName" size="20" />
            <button type="button" onclick="testPost();">Ajax Post请求</button>
        </div>
     
        <div id="myDiv" />
    
    </body>
    </html>

    客户端JS代码:

    var xmlhttp = createRequest();
    
    function testGet() {
        var fname = document.getElementById("testGetName").value;
        xmlhttp.open("GET", "Test.ashx?fname=" + fname + "&random=" + Math.random() , true);
    	xmlhttp.onreadystatechange = callback;
        xmlhttp.send(null);
    }
    
    function testPost() {
        var fname = document.getElementById("testPostName").value;
        xmlhttp.open("POST", "Test.ashx?"  + "&random=" + Math.random() , true);
        xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
    	xmlhttp.onreadystatechange = callback;
        xmlhttp.send("fname="+fname);
       
    }
    
    function createRequest() {
        var xmlhttp;
        if (window.XMLHttpRequest) {
            // code for IE7+, Firefox, Chrome, Opera, Safari
            xmlhttp = new XMLHttpRequest();
        }
        else {
            // code for IE6, IE5
            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        }
        return xmlhttp
    }
    
    function callback() {
        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
            document.getElementById("myDiv").innerHTML = xmlhttp.responseText;
        }
    }

    这里有一点需要注意

    var xmlhttp = createRequest(); 。

    1.让服务端能够操作这个变量,如果定义成局部变量,则服务端返回response时,不能对xmlhttp的属性赋值。回调函数要求request是全局的,才能访问这个变量和它的属性值。

    2.定义成全局变量后,可能出现两个请求或多个请求共享同一个请求对象。而这个请求对象只能存放一个回调函数来处理服务器响应。当服务器返回两个请求的Response后,可能会调用后指定的回调函数。所以可能有两个完全不同的服务器响应由同一个回调函数处理,而这可能并不是正确的处理。解决办法是创建两个不同的请求对象。

    服务端代码不变。

    2.输入“Jackson0714”然后点击Sumbit按钮

    页面不会刷新,在最下面显示"Hello World Jackson0714"

     

    3.AJAX发送请求和服务端返回响应的流程

    高清无码图在这里:点我查看大图!!!

    4.通过抓包,我们可以得到HTTP Headers

    浏览器发送HTTP给服务端,采取的协议是HTTP协议。

    在传输过程中,我们可以看下HTTP Headers:

     

    6.AJAX  GET和POST方式区别

    AJAX发送请求和POST发送请求的代码如下:

    //GET方式
    function testGet() {
        var fname = document.getElementById("testGetName").value;
        xmlhttp.open("GET", "Test.ashx?fname=" + fname + "&random=" + Math.random() , true);
    xmlhttp.onreadystatechange = callback;
        xmlhttp.send(null);
    }
     
    //POST方式
    function testPost() {
        var fname = document.getElementById("testPostName").value;
        xmlhttp.open("POST", "Test.ashx?"  + "&random=" + Math.random() , true);
        xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
       xmlhttp.onreadystatechange = callback;
        xmlhttp.send("fname="+fname);
       
    }
    

     

    1.请求的URL中,POST方式可以添加键值对,也可以不添加

    2.GET方式中,send方法传递值无效。对于IE浏览器可以忽略send()方法的参数。但是对于FireFox,必须提供一个null引用,否则回调行为将不规律。这是在编写客户端脚本时你会发现的一个跨浏览器兼容的问题。

    3.POST 可以用send方法发送额外信息。发送的信息存放在content中

    4.Post方式需要指定Request Header的类型。Get方式不需要指定。

    5.GET方式将参数暴露在URL中,POST不暴露。

     

    四、XMLHttpRequest 对象的知识

    1.XMLHttpRequest 对象的方法

    2.XMLHttpRequest 对象的属性

    五、JQuery实现AJAX

    下面的代码实现了当切换DropDownList的item时,触发getWeeklyCalendar方法,用JQuery的类库方法$.ajax来发送AJAX请求。

    客户端JQuery代码

    function getWeeklyCalendar(name,currentDate,mode){
       $.ajax({
            type:'POST',
            url:'weekProcess.php',data:'func=getWeeklyCalender&name='+name+'&currentDate='+currentDate+'&   mode='+mode,
            success:function(data){
            paintWeeklyCandler(data);
          }
      });
    }
    

    后台成功返回Response后,执行paintWeeklyCandler(data)方法

    后台PHP代码

    <?php
    //定义返回的Response的格式为JSON格式 header('Content-type: text/json');
    //引入自定义的数据库连接文件 include 'dbConfig.php';
    //引入自定义的设置session的文件 include_once 'session.php'; /* * Function requested by Ajax */ if(isset($_POST['func']) && !empty($_POST['func'])) { switch($_POST['func']){  case 'getWeeklyCalender':     getWeeklyCalender($_POST['name'],$_POST['currentDate'],$_POST['mode']);      break;     case 'getWeeklyStatus':     getWeeklyStatus($_POST['name'],$_POST['currentDate'],$_POST['mode']);     break;     case 'getEvents':     getEvents($_POST['date'],$_POST['name']);     break;    default:     break; } } function getWeeklyCalender($name = '',$currentDate = '',$mode = '') { //逻辑代码
       

        //返回JSON格式的Response echo json_encode(array('result'=>$DaysOfWeekResultsArray)); }
    ?>

      

    六、优势

    1.使用异步方式与服务器通信,页面不需要重新加载,页面无刷新

    2.按需取数据,减少服务器的负担

    3.使得Web应用程序更为迅捷地响应用户交互

    4.AJAX基于标准化的并被广泛支持的技术,不需要下载浏览器插件或者小程序,但需要客户允许JavaScript在浏览器上执行

    5.浏览器的内容和服务端代码进行分离。页面的内容全部由JAVAScript来控制,服务端负责逻辑的校验和从数据库中拿数据。

     

    七、缺点

    1.安全问题:将服务端的方法暴露出来,黑客可利用这一点进行攻击

    2.大量JS代码,容易出错

    3.Ajax的无刷新重载,由于页面的变化没有刷新重载那么明显,所以容易给用户带来困扰——用户不太清楚现在的数据是新的还是已经更新过的;现有的解决有:在相关位置提示、数据更新的区域设计得比较明显、数据更新后给用户提示等

    4.可能破坏浏览器后退按钮的正常行为; 

    5.一些手持设备(如手机、PAD等)自带的浏览器现在还不能很好的支持Ajax

    八、应用场景

    1.对数据进行过滤和操纵相关数据的场景

    2.添加/删除树节点

    3.添加/删除列表中的某一行记录

    4.切换下拉列表item

    5.注册用户名重名的校验

    九、不适用场景

    1.整个页面内容的保存

    2.导航

    参考资料:

    《ASP.NET 4 高级程序设计》

    《Head First AJAX》

    AJAX工作原理及其优缺点

    https://msdn.microsoft.com/zh-cn/library/1463ysyw(v=vs.110).aspx

    https://msdn.microsoft.com/en-us/library/system.web.httprequest.form.aspx

    https://msdn.microsoft.com/zh-cn/library/system.web.httpcontext.request(v=vs.80).aspx

    https://msdn.microsoft.com/zh-cn/library/system.web.httpcontext.response(v=vs.110).aspx


    作  者: Jackson0714
    出  处:http://www.cnblogs.com/jackson0714/
    关于作者:专注于微软平台的项目开发。如有问题或建议,请多多赐教!
    版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
    特此声明:所有评论和私信都会在第一时间回复。也欢迎园子的大大们指正错误,共同进步。或者直接私信
    声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是作者坚持原创和持续写作的最大动力!

  • 相关阅读:
    迭代器和生成器
    案例:复制大文件
    案例:使用seek倒查获取日志文件的最后一行
    Leetcode165. Compare Version Numbers比较版本号
    Leetcode137. Single Number II只出现一次的数字2
    Leetcode129. Sum Root to Leaf Numbers求根到叶子节点数字之和
    Leetcode116. Populating Next Right Pointers in Each Node填充同一层的兄弟节点
    Leetcode114. Flatten Binary Tree to Linked List二叉树展开为链表
    Leetcode113. Path Sum II路径总和2
    C++stl中vector的几种常用构造方法
  • 原文地址:https://www.cnblogs.com/jackson0714/p/AJAX.html
Copyright © 2011-2022 走看看