zoukankan      html  css  js  c++  java
  • 再学ajax--第一天

      今天写这个帖子就是是前几天在学ES6在学到Promise实现AJAX操作时,发现对ajax的一些知识点有些遗忘,所以就回头重新复习了一遍ajax,温故而知新。

      主要有从4个方面去复习ajax,分析不透彻的,还望海涵

          第一:AJax请求,progress,load,get/post请求方式的实现;

      第二:$.ajax,$.load,$.get,$.post,$.getScript,$.getJSON的复习和浅析源码;

      第三:请求方式post和get到底的区别在哪

      第四:es6中promise实现ajax的例子

    AJax请求,progress,load,get/post请求方式的实现

      ajax原理理解起来就是,利用XMLHttpRequest,当然IE下是ActiveXObject向服务器发送异步请求,并将服务器返回的数据交还给客户端处理,JS的DOM操作去更新页面,在form表单提交的时候,可实现页面不刷新,给用户良好的操作体验,但是有一个缺点就是没有history(-1)。

          XMLHttpRequest主要有4个属性,readystatechange  readyState   status   resopnseText

          readystatechange:改变状态时,事件触发的处理程序

       readyState

           0:对象已建立,但没有send

           1:对象已经send,正在载入

       2:载入完成

       3:解析接收到数据

       4:解析完成,可以response了

       status

          200:ok

          302:文件暂时性转移

          304:资源在上次请求后没有修改

      500:服务器内部问题

      response

         responseText:将后台的数据以text文本解析

      简单ajax请求

       ajax.php

    <?php 
        $cpage = isset($_GET["cpage"])?$_GET["cpage"]:1;    
        $url = "http://www.wookmark.com/api/json/popular?page=".$cpage;
        $content = file_get_contents($url);
        $content = iconv("gbk","utf-8",$content);
        echo $content;
     ?>

      wookmark是一个可提供图片源地址的一个站点, http://www.wookmark.com/api/json/popular?page=n (n<10)  获取到的是图片title、src等的JSON字符串,在使用前要将其JSON.parse,本例中将以这个文件作为服务器文件。

      ajax.js

            function ajax(method,url,data,success){
                var xhr = null;
                //异样检测
                try{
                    xhr = new XMLHttpRequest();
                }
                catch(e){
                    xhr = new ActiveXObject("Microsoft.XMLHTTP");
                }
                //加get请求参数
                if(method=="get" && data){
                    url+="?"+data;
                }
                //建立请求
                xhr.open(method,url,true);
                //事件触发的处理程序
                xhr.onreadystatechange=function (){
                    if(xhr.readyState===4){
                        if(xhr.status===200){
                            success && success(xhr.responseText);
                        }else{
                            alert(xhr.status);
                        }
                    }
                }
                //发送请求
                xhr.send()
    }

      上面所示的请求是包在一个函数里面的,ajax(url,method,data,callback),ajax1("get","./ajax1.php","cpage=1",function (data){}),例子是以get请求为例,post请求要setRequestHeader的content-type属性,如下所示

    xhr.setRequestHeader("content-type","application/x-www-form-urlencoded");
    xhr.send(data);
      load事件与progress事件

      onload事件可以代替onreadyStatechange 不用检查readyState的值  0 1 2 3 4,onload事件最先是由firefox提出来的。

                 xhr.onload=function (){
                         if(xhr.status === 200){
                         console.log(xhr.responseText);
                    }else{
                         console.log(xhr.status);
                     }
                }    

       onprogress可以返回进度信息

       lengthComputable :进度信息是否可用
       position/loaded:已经接收的字节数     火狐/谷歌
       tatalSize/total:http响应头Content-length预期的字节数    火狐/谷歌

           xhr.onprogress=function (event){
             var oDiv=document.getElementById("div1");
              if(event.lengthComputable){
                 console.log(event);
                 oDiv.innerHTML = event.loaded +"+"+ event.total;
             }
       get/post请求方式的实现

        get请求

            function makeuri(url,name,value){
                url+=url.indexOf("?")===-1?"?":"&";
                url+=encodeURIComponent(name)+"="+encodeURIComponent(value)
                return url;
            }
             var url = "http://www.iiiqaz.cn/ES6/ajax.html";
             url = makeuri(url,"name1","value1");
             url = makeuri(url,"name2","value2");
             xhr.open("get",url,true);
             xhr.send(null);

        request url:

       post请求

        form表单

        <form id="form" >
            <input  name="username" value="123"><br>
            <input name="useremail" value="123@qq.com">
        </form>

        post请求方式实现

        function post1(){
           var form = document.getElementById("form");
    var arr=[],formelements,names,values,len,postvalue; for(var i=0;i<form.elements.length;i++){ formelements=form.elements[i]; names = formelements.attributes[0].nodeValue; values = formelements.attributes[1].value; //console.log(values) postvalue = names +"="+ values; arr.push(postvalue); } return arr.join("&"); } xhr.open("post","./1.json",true); xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); xhr.send(post1())

          先找到form表单,遍历from表单input的元素,下图为form.elements

        

       在form.elements中找name和value元素,注意在找name元素的时候,是返回form.elements[i].nodeValue而不是form.elements[i].name

        

        将name和value都push到arrry里面,但是要转成以&为连接符的字符  return arr.join("&"),当然也不要忘记一点,就是post请求要设置requestHeader

        显示结果如下

        

    $.ajax,$.load,$.get,$.post,$.getScript,$.getJSON的复习和浅析源码;

        $.ajax()的基本用法

            $.ajax({
                type:"post",   //请求方式
                url:"./ajax1.php",   // 发送请求地址
                data: {              //发送服务器的数据
                     cpage: 2
                },
                dataType:"text",    //预期服务器返回数据的类型
                success:function (data,textStatus,jqXHR){  //请求成功后的回调函数(responseText,jqXHR)   
                     console.log(jqXHR);  //responseText text
                    console.log(textStatus);//success
                    // console.log(jqXHR);//resopnseText、readyStatus
                }
            })

      $.load()的基本用法

      DOM事件的ajax load(url,data,callback);

            $(function (){
                 // DOM事件的ajax load(url,data,callback);
                $("#div1").on("click",function (){
                     $("#div1").load("./ajax1.php","cpage=2",function (responseText,statusTxt,xhr){
                          console.log(statusTxt);  //text
                     })
                 })

      $.get()

             //$.get(url,data,callback,type)
             $.get("./ajax1.php","cpage=2",function (data,textStatus,jqXHR){
                  console.log(data); //json
                  console.log(textStatus);
                  console.log(jqXHR);
             },"json")

      $.post()

            //$.post(url,data,callback,type)
            $.post("./ajax1.php","cpage=2",function(data,textStatus,jqXHR){
                    console.log(data);//json
                    console.log(textStatus);
                    console.log(jqXHR);
            },"json")

      $.getScript()

            //$.getJSON 通过HTTP的get请求,载入js文件
            $.getScript("./ajax.js",function(data,textStatus,jqXHR){
                    console.log(data); //text
                    console.log(textStatus);
                    console.log(jqXHR);
            })

      $.getJSON()

            //$.getJSON 通过HTTP请求载入JSON数据
            $.getJSON("./ajax1.php","cpage=2",function(data,textStatus,jqXHR){
                console.log(data);//json
            })

      上面几个二级的XMLHttpRequest只有load事件返回的data类型是string,其他都是json

      当打印jqXHR时

       

      jqXHR部分的源码
    //jqXHR部分
        jqXHR = {
    
            readyState: 0,
    
            // Caches the header
            setRequestHeader: function (name, value) {
                if (!state) {
                    var lname = name.toLowerCase();
                    name = requestHeadersNames[lname] = requestHeadersNames[lname] || name;
                    requestHeaders[name] = value;
                }
                return this;
            },
    
            // Raw string
            getAllResponseHeaders: function () {
                return state === 2 ? responseHeadersString : null;
            },
    
            // Builds headers hashtable if needed
            getResponseHeader: function (key) {
                var match;
                if (state === 2) {
                    if (!responseHeaders) {
                        responseHeaders = {};
                        while ((match = rheaders.exec(responseHeadersString))) {
                            responseHeaders[match[1].toLowerCase()] = match[2];
                        }
                    }
                    match = responseHeaders[key.toLowerCase()];
                }
                return match === undefined ? null : match;
            },
    
            // Overrides response content-type header
            overrideMimeType: function (type) {
                if (!state) {
                    s.mimeType = type;
                }
                return this;
            },
    
            // Cancel the request
            abort: function (statusText) {
                statusText = statusText || "abort";
                if (transport) {
                    transport.abort(statusText);
                }
                done(0, statusText);
                return this;
            }
        };

    请求方式post和get到底的区别在哪

      在我看来,如果要从面试角度去回答,从三个角度去回答这个问题

      传输方式、大小限定、安全性

      传输方式:get的传输方式是使用的URL传递。而post数据是在http头的form-data里面

      大小限定:get传输方式大小限制在2048个字符,而post传输方式的大小是不限制的

      安全性:get传输方式的数据是所有人可见的,而post传输的数据在form-data里面,相对来说,是安全的。get传输方式是有缓存存在的,而post传输方式是没有缓存的。

      但是如果是从搞技术吹毛求疵的角度去分析这个问题,就得查RFC文献了,在对于数据的传输方式上,HTML标准对HTTP的约定,而不是HTTP规定这样的传输方式,所以会有这样让人尴尬的结果。

      具体推荐看一篇很早的贴子,也不褒贬不一的

        GET和POST有什么区别?及为什么网上的多数答案都是错的

    es6中promise实现ajax的例子

      pormise是优化事件机制和回调函数而提出的一种异步编程的解决方案,它是一个代理对象,代理了最终的返回值,返回值可以个对象下的then方法的回调函数可访问到。

      什么事异步编程?异步编程是基于事件驱动而提出来的,相对比同步I/O,CPU利用率高,I/O调用重叠进行。异步编程的最大特色就是回调函数

      什么是事件驱动?主循环加事件触发来运行程序。

      什么是同步I/O?多线程操作,分配I/O

      多线程?进程是资源的分配,线程就是资源的调度,多线程就是多次资源调度

      在js中,是单线层的,甚至于node的最大特色就是,事件驱动与异步编程,angular的最大特色就是mvvm,模型,自定义指令,数据的双向绑定。

      说偏了。。。,复习复习,可以原谅。

      说正事,那么promise实现ajax是怎么写呢?

     

        function getJSON(url){
            var pro = new Promise(function(resolve,reject){
                var xhr = null;
                try{
                    xhr = new XMLHttpRequest()
                }
                catch(e){
                    xhr = new ActiveXObject("Microsoft.XMLHTTP");
                }
                xhr.open("get",url);
                xhr.onreadystatechange=function (){
                    if(xhr.readyState===4){
                        if(xhr.status===200){
                            resolve(xhr.response);
                        }else{
                            reject(new Error(xhr.status));
                        }
                    }
                }
                xhr.send()
            })
            return pro;
        }
        getJSON("./ajax1.php").then(function(data){
            console.log(data);
        },function(error){
            console.log(error);
        })

     

     在pormise中有三种状态

      pending 进行

      resolved 成功

      reject 已完成

      而经常用的是后两个状态,来代理返回值,最终在then的回调函数中可读取到。

       参考资料:阮大神--ES6入门  MDN--promise

        

       ---end

      期待下一次复习与学习...

      

  • 相关阅读:
    光脚丫学LINQ(036):一对一映射关系
    光脚丫学LINQ(033):建立映射关系的两个实体类必须分别包含一个主键列成员
    ASP.NET4的网页指令
    光脚丫学LINQ(032):探究AssociationAttribute.Storage
    [代码]服务器端的隐藏重定向
    maven项目bulid失败_No compiler is provided in this environment.
    [SC] OpenSCManager 失败 5:拒绝访问
    c3p0连接池:com.mysql.cj.exceptions.InvalidConnectionAttributeException
    iframe高度自适应
    彻底卸载mysql数据库~
  • 原文地址:https://www.cnblogs.com/dirkhe/p/6947824.html
Copyright © 2011-2022 走看看