前言
最近在為單位做一個簡單的手機App,基於Qt技術棧的選擇了QtQuick來開發。不得不說QtQucik開發的確舒服,很多東西都不用寫就可以只用,UI定義起來也比較自由。但是本人想通過cookie來作為登陸驗證時就發現,QtQuick實現起來相當麻煩。(主要是沒有文檔,資料只找到一篇qyvlik寫的。我也不想直接用WebEngine)
不帶cookie
可以使用XMLHttpRequest,比較坑的是官方竟然沒有任何案例,不過Api都是與js的XmlHttpRequest一樣的,以下是qyvlik封裝的一套分辨操作函數:
//通過Json對象輸出url的query字符串
function urlQuery(jsonObject) {
var query = "";
var i = 0;
for(var iter in jsonObject) {
if(i > 0) {
query += "&";
}
query += iter +"=" + encodeURI(jsonObject[iter]);
i++;
}
// console.log("url query:", query);
return query;
}
//設置頭
function setHeader(xhr, headers) {
//"Content-Type":"application/x-www-form-urlencoded"
for(var iter in headers) {
xhr.setRequestHeader(iter, headers[iter]);
}
}
//這里我修改了一下函數的形參,從使用的角度來看,回調函數一般都會有,但是headers不一定要設置,所以調換了一下位置
function ajax(method, url, callable,headers,data) {
headers = headers || {};
callable = callable || function(xhr) {
console.log("沒有設置callable,使用默認log函數")
console.log(xhr.status);
console.log(xhr.responseText);
}
var xhr = new XMLHttpRequest;
xhr.onreadystatechange = function() {
if(xhr.readyState == xhr.DONE) {
callable(xhr);
}
}
xhr.open(method, url);
setHeader(xhr, headers);
if("GET" === method) {
xhr.send();
} else {
xhr.send(data);
}
}
為了能夠重復利用,本人將這些代碼都放入一個js文件中,之后使用導入的方式重復利用。(注意:導入的命名控件首字母需要大寫)
import "xmlhttprequest.js" as XmlHttpRequest
使用:
var jsonObject={user:"admin",password:Qt.md5("123")};
XmlHttpRequest.ajax("GET","http://192.168.3.108:3000/landing"+"?"+XmlHttpRequest.urlQuery(jsonObject),function(xhr){
console.log(xhr.status);
console.log(xhr.responseText);
if(JSON.parse(xhr.responseText).message==="ok") {
stack.push("qrc:/resource/qml/listview.qml",{stack:stack,uifont:uifont});
}else{
message.show("用戶名或者密碼錯誤!",2000);
}
});
帶cookie
因為XmlHttpRequest是不能帶有cookie的,所以只能通過c++導出QNetworkAccessManager、QNetworkRequest、QNetworkReply,具體的代碼可以參考https://github.com/qyvlik/QmlNetwork。qyvlik封裝了一套QML對象,我直接拿來用了,很可惜他的使用說明寫的不太詳細,有一些操作需要直接看他寫的微信案例才能搞定。
NetworkAccessManager { id: manager }
NetworkResponse { id: response }
NetworkRequest { id: request }
Buffer { id: buffer }
function initWebWeiXinInfo() {
var url = "http://192.168.3.108:3000/landing";
var data = {
user:"admin",
password:"123"
};
if(buffer.isOpen()) {
buffer.close();
}
buffer.data = JSON.stringify(data);
if(!buffer.open(IODevice.ReadOnly)) {
console.log(buffer.errorString());
}
request.clear();
request.url = url;
// request.setHeader("Cookie", cookie);
request.setHeader("Content-Type", "application/json")
request.ioDevice = buffer;
connectSignalOnce(response.finished,function() {
console.log("data:", buffer.data)
var headers = response.getAllResponseHeaders();
for(var iter in headers) {
console.log(headers[iter]);
}
console.log(response.responseContent);
});
manager.post(request, response);
}
結語
感覺qyvlik封裝的東西比較多,需求上本人也就用用Get與Post以及cookie,以后有時間會重新封裝一個簡單版本。