原生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> 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM