使用AJAX技術發送異步請求,HTTP服務端推送 --


使用AJAX技術發送異步請求

什么是AJAX

AJAX指一步Javascript和XML(Asynchronous JavaScript And XML),它是一些列技術的組合,簡單來說AJAX基於XMLHttpRequest讓我們在不重載頁面的情況下和服務器進行數據交換。

加上JavaScript和DOM(Document Object Model,文檔對象模型),我們就可以在接收到響應數據后局部更新頁面。XML指的是數據的交互模式,可以是純文本(Plain Text)、HTML或JSON。

 

使用jQuery發送AJAX請求

jQuery是流行的JavaScript庫,它包裝了JavaScript,讓我們通過更簡單的方式編寫JavaScript代碼。對於AJAX,它提供了多個相關的方法,使用它可以很方便地實現AJAX操作。更重要的是,jQuery處理了不同瀏覽器的AJAX兼容問題,我們只需要編寫一套代碼,就可以在所有主流瀏覽器上運行。

 

 

在示例中,使用全局jQuery函數ajax()發送AJAX請求。ajax()函數是底層函數,有豐富的自定義配置,支持的主要參數如下:

 

jQuery還提供了快捷方法:用戶發送GET請求的get()方法和用於發送POST請求的post()方法,還有直接用於獲取json數據的getjson()以及獲取腳本的getscript()方法。這些方法都是基於ajax()方法實現的。

 

返回“局部數據”

對於處理AJAX請求的視圖函數來說,不會返回完整的HTML響應,這時一般會返回局部數據,常見的類型有純文本或局部HTML模板、JSON數據或者空值

 

下面程序對應的頁面中,我們顯示一片很長的虛擬文章,文章正下方有一個”Load More”的按鈕,當按鈕被單擊時,會發送一個AJAX請求獲取文章的更多內容並直接動態插入到文章下方。

用來顯示虛擬文章視圖是show_post

 

文章的隨機正文通過Jinja2提供的generate_Jorem_ipsum()函數生成,n參數用來指定段落的數量,默認為5,它會返回由隨機字符組成的虛擬文章。文章下面添加了一個”Load More”按鈕。按鈕下面是兩個<script></script>代碼塊,第一個script是從CDN加載jQuery資源。

在第二個script標簽中,我們在代碼的最外層創建了一個$(function(){…})函數,這個函數是常見的$(document).ready(function(){…})函數的簡寫形式。這個函數用來在頁面DOM加載完畢后執行代碼,類似傳統JavaScript中的window.onload方法,所以我們通常會將代碼包裝在這個函數中。美元符號是jQuery的簡寫,我們通過它來調用jQuery提供的多個方法,所以$.ajax()等同於jQuery.ajax()。

 

在$(function(){…})中,$(‘#load’)被稱為選擇器,我們在括號中傳入目標元素的id、class或是其他屬性來定位對應的元素,將其創建為jQuery對象。我們傳入了”Load More”按鈕的id值以定位到加載按鈕。在這個選擇器上,我們附加了.click(function(){…}),這會為加載按鈕注冊一個單擊事件處理函數,當加載按鈕被單擊時就會執行單擊事件回調函數。在這個回調函數中,我們使用$.ajax()方法發送一個AJAX請求到服務器,通過url將目標URL設為”/more”,通過type參數將請求的類型設為GET。當請求成功處理並返回2xx響應或304響應,會觸發success回調函數。success回調函數接收的第一個參數為服務器端返回的響應主體,在這個回調函數中,我們在文章正文(通過$(‘.body’)選擇)底部使用append()方法插入返回的data數據。

 

 

from jinja2.utils import generate_lorem_ipsum

@app.route('/post')
def show_post():
    post_body = generate_lorem_ipsum(n=2)#生成兩段隨機文本
   
return u'''
    <h1>A very long post</h1>
    <div class="body">%s</div>
    <button id="load"> Load More</button>
    <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
    <script type="text/javascript">
    $(function() {
        $('#load').click(function() {
            $.ajax({
                url: '/more', //
目標URL
                type: 'get', // 請求方法
                success: function(data){ // 返回2XX響應后觸發的回調函數
                    $('.body').append(data); // 將返回的響應插入到頁面中
                    }
                })
            })
    })
    </script>'''
%post_body


@app.route('/more')
def load_post():
    return generate_lorem_ipsum(n=1)


if __name__ == '__main__':
    app.run(debug = True)

結果:
訪問127.0.0.1:5000/post頁面

 

點擊Load More按鈕,瀏覽器會在后台發送一個GET請求到/more,這個視圖返回的隨機字符會被動態的插入到文章下方
可以看到頁面沒有刷新,只是在底部多顯示了一段內容

 

再次點擊按鈕

 

HTTP服務器端推送

不論是傳統的HTTP請求-響應式的通信模式,還是一部的AJAX式請求,服務器端始終處於被動的應答狀態,只有在客戶端發出請求的情況下,服務器端才會返回響應。這種通信模式被稱為客戶端拉取。

在某些場景下,需要的通信模式是服務器端的主動推送。比如一個聊天室有很多用戶,當某個用戶發送消息后,服務器接收到這個請求,然后把消息推送給聊天室的所有用戶。

類似這種關注實時性的情況還有很多,比如社交網站的導航欄實時顯示新提醒和私信的數量,用戶的在線狀態更新,股價行情監控、顯示商品庫存信息、多人游戲、文檔協作等。

 

實施服務器桂松的一些列技術被合稱為HTTP Server push(http服務器端推送),目前常用的推送技術如下:

 

 

輪詢(polling)這類使用AJAX技術模擬服務器端推送的方法實現起來比較簡單,但通常會造成服務器資源上的浪費,增加服務器的負擔,而且會讓用戶的設備消耗更多的電量(頻繁的發起異步請求)。SSE效率更高,在瀏覽器的兼容性方面,除了windows IE/Edge,SSE(server-sent event)基本支持所有主流瀏覽器,但瀏覽器通常會限制標簽頁的鏈接數量。

 

除了這些推送技術,在HTML5的API中還包含了一個WebSocket協議,和HTTP不同,它是一種基於TCP協議的全雙工通信協議。和前面說的服務器端推送技術相比,WebSocket實時性更強,而且可以實現雙向通信。另外,WebSocket的瀏覽器兼容性要強於SSE。

 


免責聲明!

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



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