Qt+QtWebApp開發(fā)筆記(五):http服務(wù)器html中使用json觸發(fā)ajax與后臺(tái)交互實(shí)現(xiàn)數(shù)據(jù)更
前言
??前面完成了頁面的跳轉(zhuǎn)、登錄,很多時(shí)候不刷新頁面就想刷新局部數(shù)據(jù),此時(shí)ajax就是此種技術(shù),且是異步的。
??本篇實(shí)現(xiàn)網(wǎng)頁內(nèi)部使用js調(diào)用ajax實(shí)現(xiàn)異步交互數(shù)據(jù)。
??在js中使用 ajax是通過XMLHttpRequest來實(shí)現(xiàn)的。
Demo
??

下載地址
??鏈接:https://pan.baidu.com/s/1tJMTPhIIyVE40qWxRWcmVA?pwd=1234
Ajax與XMLHttpRequest
Ajax
??Ajax即Asynchronous Javascript And XML(異步JavaScript和XML)在 2005年被Jesse James Garrett提出的新術(shù)語,用來描述一種使用現(xiàn)有技術(shù)集合的‘新’方法,包括:HTML或XHTML、CSS、JavaScript、DOM、XML、XSLT以及最重要的XMLHttpRequest。使用Ajax技術(shù)網(wǎng)頁應(yīng)用能夠快速地將增量更新呈現(xiàn)在用戶界面上,而不需要重載(刷新)整個(gè)頁面,這使得程序能夠更快地回應(yīng)用戶的操作。
??Ajax不是一種新的編程語言,而是一種用于創(chuàng)建更好更快以及交互性更強(qiáng)的Web應(yīng)用程序的技術(shù)。使用JavaScript向服務(wù)器提出請(qǐng)求并處理響應(yīng)而不阻塞用戶核心對(duì)象XMLHttpRequest。通過這個(gè)對(duì)象,JavaScript可在不重載頁面的情況與Web服務(wù)器交換數(shù)據(jù),即在不需要刷新頁面的情況下,就可以產(chǎn)生局部刷新的效果。Ajax在瀏覽器與 Web 服務(wù)器之間使用異步數(shù)據(jù)傳輸(HTTP 請(qǐng)求),這樣就可使網(wǎng)頁從服務(wù)器請(qǐng)求少量的信息,而不是整個(gè)頁面。
Ajax可使因特網(wǎng)應(yīng)用程序更小、更快,更友好。
Ajax是一種獨(dú)立于Web服務(wù)器軟件的瀏覽器技術(shù)。
Ajax基于Web標(biāo)準(zhǔn):JavaScript、XML、HTML與CSS,在Ajax中使用的Web標(biāo)準(zhǔn)已被良好定義,并被所有的主流瀏覽器支持。
Ajax用程序獨(dú)立于瀏覽器和平臺(tái)。
??Web應(yīng)用程序較桌面應(yīng)用程序有諸多優(yōu)勢(shì);它們能夠涉及廣大的用戶,它們更易安裝及維護(hù),也更易開發(fā)。但是,因特網(wǎng)應(yīng)用程序并不像傳統(tǒng)的桌面應(yīng)用程序那樣完善且友好。?通過 Ajax,因特網(wǎng)應(yīng)用程序可以變得更完善,更友好。
XMLHttpRequest
??XMLHTTP是一組API函數(shù)集,可被JavaScript、JScript、VBScript以及其它web瀏覽器內(nèi)嵌的腳本語言調(diào)用,通過HTTP在瀏覽器和web服務(wù)器之間收發(fā)XML或其它數(shù)據(jù)。XMLHTTP最大的好處在于可以動(dòng)態(tài)地更新網(wǎng)頁,它無需重新從服務(wù)器讀取整個(gè)網(wǎng)頁,也不需要安裝額外的插件。該技術(shù)被許多網(wǎng)站使用,以實(shí)現(xiàn)快速響應(yīng)的動(dòng)態(tài)網(wǎng)頁應(yīng)用。例如:Google的Gmail服務(wù)、Google Suggest動(dòng)態(tài)查找界面以及Google Map地理信息服務(wù)。
??XMLHTTP是AJAX網(wǎng)頁開發(fā)技術(shù)的重要組成部分。除XML之外,XMLHTTP還能用于獲取其它格式的數(shù)據(jù),如JSON或者甚至純文本。
??使用XMLHttpRequest來發(fā)送HTTP請(qǐng)求以實(shí)現(xiàn)網(wǎng)站和服務(wù)器之間的數(shù)據(jù)交換。
??XMLHttpRequest對(duì)象是Ajax的核心,它有許多的屬性、方法和事件。
屬性
readyState:當(dāng)前狀態(tài)
??當(dāng)一個(gè)XMLHttpRequest對(duì)象被創(chuàng)建后,readyState屬性標(biāo)識(shí)了當(dāng)前對(duì)象的狀態(tài)。
??

responseText:響應(yīng)文本
responseText屬性包含客戶端接收到的HTTP響應(yīng)的文本內(nèi)容。
readyState為0、1、2時(shí):為一個(gè)空字符串;
readyState為3時(shí):為還未完成的響應(yīng)信息;
readyState為4時(shí):為含完整的響應(yīng)信息;
statusText:狀態(tài)文本
??描述了HTTP狀態(tài)代碼文本,并且僅當(dāng)readyState屬性值為3或4時(shí)才可用。檢測(cè)返回結(jié)果的判斷就是:
if(readyState===4 && statusText===200){
……}
??如我們的Demo:
??

函數(shù)
open():初始化請(qǐng)求
open(method, url, async, username, password)
參數(shù)method:請(qǐng)求的類型,GET、POST、PUT、DELETE、HEAD類型,輸入的時(shí)候使用大寫;
參數(shù)url:請(qǐng)求的資源地址,請(qǐng)求資源的web api地址;
參數(shù)async:是否發(fā)送異步請(qǐng)求,true-異步請(qǐng)求,false-同步請(qǐng)求;
參數(shù)username(可為空):需要服務(wù)器驗(yàn)證訪問用戶時(shí),設(shè)置username;
參數(shù)password(可為空):需要服務(wù)器驗(yàn)證訪問用戶時(shí),設(shè)置password;
send():發(fā)送請(qǐng)求
??調(diào)用open()方法后,再調(diào)用send()方法將請(qǐng)求發(fā)送。當(dāng)open()方法中async參數(shù)為true(異步)時(shí),在send()方法調(diào)用后立即返回,否則將會(huì)中斷直到請(qǐng)求返回。
setRequestHeader():設(shè)置頭部信息
??設(shè)置請(qǐng)求的頭部信息
getResponseHeader():獲取頭部信息
??獲取請(qǐng)求的頭部信息
事件
??onreadystatechange:狀態(tài)變化事件
??當(dāng)readyState屬性值發(fā)生改變時(shí),就會(huì)觸發(fā)onreadystatechang事件,代碼中是依賴onreadystatechang進(jìn)一步判斷狀態(tài)和狀態(tài)文本來做處理。
??

使用XMLHttpRequest的步驟
步驟一:在腳本中實(shí)例化XHMLHttpRequest
var xhr = new XMLHttpRequest();
步驟二:初始化請(qǐng)求open()
xhr.open('GET','/checkState/data',true);
步驟三:發(fā)送請(qǐng)求
xhr.send();
步驟四:書寫事件處理函數(shù)并判斷狀態(tài)和狀態(tài)文本
xhr.onreadystatechange = function() {
if(xhr.readyState === 4 && xhr.status === 200)
{
…… }}
步驟五:書寫返回成功的js處理代碼
document.getElementById("dt2").innerHTML = xhr.responseText;
Demo增量使用ajax交互過程
步驟一:準(zhǔn)備代碼模板
??準(zhǔn)備之前的demo v1.3.0模板:
??

步驟二:新增checkState.html頁面
??下面是新增定時(shí)獲取和手動(dòng)按鈕獲取得html:
??

步驟三:創(chuàng)建CheckStateRequestHandle處理
??新建了一個(gè)處理,特別是增加了對(duì)于ajax技術(shù)的路徑處理
??

??

步驟四:將CheckStateRequestHandle接入
??

??

Demo源碼
checkState.html
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>長沙紅胖子Qt</title></head><body>
<p><a>這里是檢測(cè)狀態(tài)Demo v1.4.0了</a></p>
<p><a id="dt1">123.567</a></p>
<p><a id="dt2">123.567</a></p>
<p><a id="dt3">123.567</a></p>
<p><button onclick="reset()">清空</button></p>
<p><button onclick="getDt1()">獲取</button></p>
<script>
function reset() {
document.getElementById("dt1").innerHTML="---.---";
document.getElementById("dt2").innerHTML="---.---";
document.getElementById("dt3").innerHTML="---.---";
}
function getDt1() {
var xhr = new XMLHttpRequest();
xhr.open('GET','/checkState/data',true);
xhr.send();
xhr.onreadystatechange = function() {
if(xhr.readyState === 4 && xhr.status === 200)
{
document.getElementById("dt1").innerHTML = xhr.responseText;
}
}
}
</script>
<script>
/* 定時(shí)獲取dt2 */
function getDt2() {
var xhr = new XMLHttpRequest();
xhr.open('GET','/checkState/data',true);
xhr.send();
xhr.onreadystatechange = function() {
if(xhr.readyState === 4 && xhr.status === 200)
{
document.getElementById("dt2").innerHTML = xhr.responseText;
}
}
}
window.setInterval(getDt2, 1000);
</script></body>
CheckStateRequestHandler.h
#ifndef CHECKSTATEREQUESTHANDLER_H#define CHECKSTATEREQUESTHANDLER_H#include "httprequesthandler.h"using namespace stefanfrings;class CheckStateRequestHandler : public HttpRequestHandler{public:
? ?CheckStateRequestHandler(QObject *parent = 0);public:
? ?void service(HttpRequest& request, HttpResponse& response);private:
? ?QTextCodec *_pTextCodec;};#endif // CHECKSTATEREQUESTHANDLER_H
CheckStateRequestHandler.cpp
#include "CheckStateRequestHandler.h"#include "DataManager.h"#include <QTextCodec>#include <QApplication>#include <QDebug>#include <QDateTime>//#define LOG qDebug()<<__FILE__<<__LINE__//#define LOG qDebug()<<__FILE__<<__LINE__<<__FUNCTION__//#define LOG qDebug()<<__FILE__<<__LINE__<<QThread()::currentThread()//#define LOG qDebug()<<__FILE__<<__LINE__<<QDateTime::currentDateTime().toString("yyyy-MM-dd")#define LOG qDebug()<<__FILE__<<__LINE__<<QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz")using namespace stefanfrings;CheckStateRequestHandler::CheckStateRequestHandler(QObject *parent)
? ?: HttpRequestHandler(parent){
? ?// 返回文本(我們需要在瀏覽器上看,所以將Qt內(nèi)部編碼都轉(zhuǎn)成GBK輸出即可,不管他本身是哪個(gè)編碼)
? ?// WINDOWS: GBK ?GB2312
? ?// LINUX ?: urf-8// ? ?_pTextCodec = QTextCodec::codecForName("utf-8");
? ?_pTextCodec = QTextCodec::codecForName("GBK");}void CheckStateRequestHandler::service(HttpRequest &request, HttpResponse &response){
? ?QString str;
? ?QString path = request.getPath();
? ?LOG << path;
? ?if(path == "/checkState")
? ?{
? ? ? ?// 為了方便,開始單獨(dú)加載html文件做處理
? ? ? ?QString filePath = QString("%1/html/checkState.html").arg(qApp->applicationDirPath());
? ? ? ?QFile file(filePath);
? ? ? ?if(!file.open(QIODevice::ReadOnly))
? ? ? ?{
? ? ? ? ? ?str = QString("The URL is wrong, no checkState.html [%1]").arg(filePath);
? ? ? ?}else{
? ? ? ? ? ?str = file.readAll();
? ? ? ? ? ?file.close();
? ? ? ?}
? ?}else if(path == "/checkState/data")
? ?{
? ? ? ?str = DataManager::getInstance()->getDt1Value();
? ?}else {
? ? ? ?response.setStatus(404,"Not found");
? ? ? ?str = "The URL is wrong, no such document.";
? ?}
? ?// 返回文本(我們需要在瀏覽器上看,所以將Qt內(nèi)部編碼都轉(zhuǎn)成GBK輸出即可,不管他本身是哪個(gè)編碼)// ? ?QByteArray byteArray = _pTextCodec->fromUnicode(str);
? ?QByteArray byteArray = str.toUtf8();
? ?response.write(byteArray);}
工程模板v1.4.0
??
