• 原生Ajax使用


    Ajax基础

    Ajax(Asynchronous JavaScript And XML)概念:
    通过XMLHttpRequest对象向服务器提出请求并处理响应,进行页面的局部更新。

    AJAX都有哪些优点和缺点?

    ajax的优点:
    1、最大的一点是页面无刷新,用户的体验非常好。
    2、使用异步方式与服务器通信,具有更加迅速的响应能力。
    3、“按需取数据”,可以最大程度的减少冗余请求,和响应对服务器和带宽的负担,节约空间和宽带租用成本。
    4、基于标准化的并被广泛支持的技术,不需要下载插件或者小程序。

    ajax的缺点:
    1、ajax不支持浏览器back按钮。
    2、安全问题 AJAX暴露了与服务器交互的细节。
    3、对搜索引擎的支持比较弱。
    4、破坏了程序的异常机制。
    5、不容易调试。

    ajax就会面临两个不可避免的问题:

    一是以何种格式来减缓数据;

    二是如何解决跨域问题。ajax本身不支持跨域请求,需要在服务器端处理--JSONP(一种跨域数据交互协议)

    相关介绍:

    现在 W3C 官方都不提倡 XHR 了,而是提倡 FetchAPI(虽然也不好用)
     Ajax 指的是 XMLHttpRequest(XHR),未来现在已被 Fetch 替代;
    Fetch API 是基于 Promise 设计,有必要先学习一下 Promise
    https://www.cnblogs.com/hsprout/p/5504053.html
    https://blog.csdn.net/shendeguang/article/details/72818802
    https://segmentfault.com/a/1190000003810652

    Ajax请求过程

    创建XMLHttpRequest、连接服务器、发送请求、服务器做出响应、接收响应数据

    浏览器端

        一:创建XMLHttpRequest对象  

        所有现代浏览器均支持 XMLHttpRequest 对象(旧版IE除外,IE5和IE6使用new ActiveXObject()

        由于不同浏览器的控件不同,所以为了兼容性,需要根据当前页面所在浏览器以不同方式获取到XMLHttpRequest对象:先检查浏览器是否支持 XMLHttpRequest 对象。如果支持,则创建 XMLHttpRequest 对象。如果不支持,则创建 ActiveXObject。

    var xmlhttp; 
    if (window.XMLHttpRequest) { //检查浏览器的XMLHttpRequest属性,如果为真则支持XMLHttpRequest
    // IE7+, Firefox, Chrome, Opera, Safari 浏览器支持XMLHttpRequest 
    xmlhttp=new XMLHttpRequest(); 
    } else { 
    // IE6, IE5 浏览器使用ActiveXObject
    xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); 
    }

    二:向服务器URL发出请求,传递参数   

        我们使用 XMLHttpRequest对象的open() 方法连接到服务器某url,设置回调函数监听返回结果、最后send() 并发出请求、传参。
    方法 描述
    open(method,url,async) 请求类型、URL 以及是否异步处理请求。
    method:请求的类型;GET 或 POST
    url:处理请求的文件在服务器上的位置
    async:true(异步)或 false(同步)
    send(string)

    将请求发送到服务器。
    string:仅用于 POST 请求。如果上面open中设置请求方法为GET,则此处send(null),若上面

    为Post,则send("para1=val1 & para2=val2...")传递参数

         GET方式:在open()方法的url参数后面拼接参数,然后send()发送一个请求过去即可。

          --用于获取数据(如浏览贴子)把数据放在URL(网址)里面来提交;安全性低、容量低、便于分享(将网址发给别人)

         POST方式:open()方法URL不携带参数,在send()中传递参数列表发送请求,并且在发送请求前需要设置请求头的Content-Type属性。

          --用于上传数据(如用户注册)把数据放在不是URL的地方;安全性一般、容量几乎无限、不便于分享

         而设置回调函数是通过

    xmlHttp.onreadystatechange = 回调函数;

        实现的,这里注意:回调函数赋值给xmlHttp.onreadystatechange时不能带(),只是把函数名赋值。

    Ajax请求总共有八种Callback:
    onSuccess
    onFailure
    onUninitialized
    onLoading
    onLoaded
    onInteractive
    onComplete
    onException
    XMLHttpRequest对象的常用方法和属性:
    open(“method”,”URL”) 方法,建立对服务器的调用
    send()方法,发送具体请求
    abort()方法,停止当前请求
    readyState属性 请求的状态 有5个可取值0=未初始化 ,1=正在加载,2=已加载,3=交互中,4=完成
    reponseXML 属性 服务器的响应,表示为XML
    status 服务器的HTTP状态码
    
    框架(架包):
    dojo, Prototype , JQuery, Dwr, extjs 等等

        所以Ajax向服务器发出请求的操作步骤为:

        1:通过xmlHttp.open()设置发送请求的目标url,并指明发送方式、是否异步处理请求(一般选true);

        2:为xmlHttp.onreadystatechange设置回调函数处理返回结果

        3:通过xmlHttp.send()发出请求

    GET方式:
    xmlHttp.open("GET", "url?参数=val & ...", true);
    xmlHttp.onreadystatechange = callback;
    xmlHttp.send(null);
    POST方式:
    xmlHttp.open("POST", url, true);
    xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");//用post方法的话,一定要加这句设置请求头的contentType属性
    xmlHttp.onreadystatechange = callback;
    xmlHttp.send("参数=val &...");    //在send方法中传递参数。

     三:定义回调函数callback,监听onreadystatechange事件,处理返回结果

        XMLHttpRequest 对象有三个重要的属性:
    属性 描述
    onreadystatechange 值是一个函数,每当 readyState 属性改变时,就会调用该函数。
    readyState 存有 XMLHttpRequest 的状态。从 0 到 4 发生变化。
    0: 请求未初始化
    1: 服务器连接已建立
    2: 请求已接收
    3: 请求处理中
    4: 请求已完成,且响应已就绪
    status 200: 请求处理成功
    404: 未找到页面

         onreadystatechange 事件   

         当请求被发送到服务器时,服务器对请求进行处理并作出响应,而对请求的处理的不同阶段对应不同的readyState,readyState 属性存有 XMLHttpRequest 的状态信息。每当 readyState改变时,就会触发onreadystatechange 事件。
         我们使用一个回调函数处理onreadystatechange 事件,函数一般格式为:
    if (xmlhttp.readyState==4 && xmlhttp.status==200){
      处理结果;
    }else{
      错误提示;
    }

        处理结果

        服务器与浏览器的信息传递归根到底是IO流的传输,而IO流传输的是字节流、字符流。但是,我们知道简单的字符串有时候不能很好地表达我们的结果,比如:返回结果是一组对象。这时候我们就可以用某种易于携带数据、易解析的字符串来传递结果了。在Ajax中,返回的结果类型可以有多种,普通文本、XML、JSON、Html等都可以,而这多种结果类型最终只用xmlhttprequest的两个属性获取:

    属性 描述
    responseText 获得字符串形式的响应数据。包括普通文本、json字符串、html字符串
    responseXML 获得 XML 形式的响应数据并解析成xml的document对象。

        XML格式的结果字符串可以用responseXML获取并解析成xml的document对象进行结点访问与内容提取;普通文本、json字符串、html字符串(少用)则通过responseText获取,普通文本结果直接使用,json字符串通过eval(jsonstring)解析成json对象来使用,html字符串则用来改变html页面的某处代码。

    if(ID=="getTXT"){    
                //以普通文本返回:
                var str = xmlHttp.responseText;  
                }
                        
    if(ID=="getXML"){
                //以xml文档返回:
                    var xmldoc = xmlHttp.responseXML;
                            var nodes=xmldoc.getElementsByTagName("标签名");   //按标签解析为数组
                            for(var i=0;i<nodes.length;i++)  
                            {  
                                提取结点值并使用; 
                            }
                        }
                        
    if(ID=="getJSON"){
                  //以json文档返回:json数据的处理统一先用responseText作为一个字符串接收后再转为json对象进行处理
                   var str = xmlHttp.responseText; 
                   var json = eval('(' + str + ')');
                   通过json.XX提取内容  
                     }

    服务器端

        服务器端定义一个servlet进行请求处理,然后返回结果。

        返回结果的步骤:

        1:设置响应编码格式;

        2:设置响应的Content-Type;

        3:拼接结果字符串:XML格式的结果需要用StringBuffer或StringBuilder来拼接。一定要先加XML标准定义:<?xml version="1.0" encoding="utf-8"?>   

        4:获取响应输出流;

        5:通过输出流向浏览器传输结果字符串;

    public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
                
            request.setCharacterEncoding("UTF-8"); 
            String ID = request.getParameter("ID");        
                if("getTXT".equals(ID)){
                getTXT(request, response);
            }else if("getXML".equals(ID)){
                getXML(request, response);
            }else if("getJSON".equals(ID)){
                getJSON(request, response);
            }    
        }
            
        public void getTXT(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            response.setCharacterEncoding("UTF-8");     
            response.setContentType("text/plain; charset=UTF-8");
            PrintWriter out = response.getWriter();
            out.write("普通文本值");     
            out.close();
        }
        
        public void getXML(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            response.setCharacterEncoding("UTF-8");     
            response.setContentType("text/xml; charset=UTF-8");
            PrintWriter out = response.getWriter();
            //XML格式的结果需要用StringBuffer或StringBuilder来拼接。切记:一定要先加XML标准定义<?xml version="1.0" encoding="utf-8"?>    
            StringBuffer sb = new StringBuffer("<?xml version="1.0" encoding="utf-8"?>");
            sb.append("<root><node>结点值</node></root>");        
            out.write(sb.toString());  
            out.close();
        }
        
        public void getJSON(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
    
            response.setCharacterEncoding("UTF-8");     
            response.setContentType("application/json; charset=UTF-8");
            PrintWriter out = response.getWriter();
            out.write("{JSON字符串}");
            out.close();
        }

     实例:

    //(原生js实现Ajax)实例1:
    //Ajax封装函数
    function Ajax(type, url, data, success, failed){
        // 创建ajax对象
        var xhr = null;
        if(window.XMLHttpRequest){//非IE浏览器
            xhr = new XMLHttpRequest();
        } else if {//IE浏览器
            xhr = new ActiveXObject('Microsoft.XMLHTTP')
        }else{
        alert("该浏览器不支持Ajax!");
        }
    
        // 用于清除缓存
        var random = Math.random();
     
        if(typeof data == 'object'){
            var str = '';
            for(var key in data){
                str += key+'='+data[key]+'&';
            }
            data = str.replace(/&$/, '');
        }
     
        if(type.toUpperCase() == 'GET'){
            if(data){
                xhr.open('GET', url + '?' + data, true);
            } else {
                xhr.open('GET', url + '?t=' + random, true);
            }
            xhr.send();
     
        } else if(type.toUpperCase() == 'POST'){
            xhr.open('POST', url, true);
            // 如果需要像 html 表单那样 POST 数据,请使用 setRequestHeader() 来添加 http 头。
            xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
            xhr.send(data);
        }
     
        // 处理返回数据
        xhr.onreadystatechange = function(){
            if(xhr.readyState == 4){
            /*
            ** Http状态码
            ** 1xx :信息展示
            ** 2xx :成功
            ** 3xx :重定向
            ** 4xx : 客户端错误
            ** 5xx :服务器端错误
            */
                if(xhr.status == 200){
                    success(xhr.responseText);
                } else {
                    if(failed){
                        failed(xhr.status);
                    }
                }
            }
        }
    }
    // 测试调用
    var sendData = {name:'asher',sex:'male'};
    Ajax('get', 'data/data.html', sendData, function(data){
        console.log(data);
    }, function(error){
        console.log(error);
    });

    JSONP实现跨域实例:

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
    <html>  
    <head>  
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
    <title>JSONP实现跨域</title>  
    <script type="text/javascript" src="jquery-1.10.2.js"></script>  
    </head>  
    <script type="text/javascript">  
    $(function(){     
        /*  
        //简写形式,效果相同  
        $.getJSON("http://app.example.com/base/json.do?sid=1494&busiId=101&jsonpCallback=?",  
                function(data){  
                    $("#showcontent").text("Result:"+data.result)  
        });  
        */  
        $.ajax({  
            type : "post",  
            async:false,  // 使用同步操作
            url : "http://10.64.22.11/service/promotion/intention/intentionResult?token=5f25d0b83d774abd941aa5309bf081f7&userid=4221",  
            dataType : "jsonp",//数据类型为jsonp  
    
            jsonp: "jsonpCallback",//服务端用于接收callback调用的function名的参数  
            success : function(data){  
                $("#showcontent").text("Result:"+data.result)  
            },  
            error:function(){  
                alert('fail');  
            }  
        });   
    });  
    </script>  
    <body>  
    <div id="showcontent">请求结果:</div>  
    </body>  
    </html> 
  • 相关阅读:
    Spring实现Nacos作为配置中心
    Machine Learning(2)——knearest neighbor算法
    Yahoo邮箱中全部邮件的下载保存
    C++中的枚举值类型转化为整数和字符串
    使用两次Hash的Hash表——Twice_Hash_Map
    符号化表达式设计(一)
    Flex和Bison的一些笔记(一)
    Makefile
    硬件设置
    谁知道广东省DB44的GPS算法?
  • 原文地址:https://www.cnblogs.com/huangdabing/p/9249216.html
Copyright © 2020-2023  润新知