前言
AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML),通过构建一个 XMLHttpRequest 对象,异步的与服务端交换数据。
QML 除了能用 C++ 封装网络组件外,也可以使用 JS 的 AJAX 去请求网络数据。
对于 AJAX 的基本知识可以百度,或者 菜鸟教程 ,或者 W3C教程 。
QML 中 GET 和 POST 基本使用一个简单的例子如下,演示了 GET/POST 请求带字符串参数的收发:
import QtQuick 2.12
Text{
id: txt
font.pixelSize: 30
function request() {
let xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
//XMLHttpRequest.DONE为状态枚举值4
if(xhr.readyState === 4) {
print('request DONE',xhr.status);
if(xhr.status === 200){
txt.text = xhr.responseText.toString();
}
}
}
//【get】
//xhr.open("GET", "http://127.0.0.1:54321/text?arg=Haha");
//xhr.send();
//【post】
xhr.open("POST", "http://127.0.0.1:54321/text");
//如果要使用post提交数据,添加此行
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.send("arg=Xixi");
}
Component.onCompleted: request()
}
GET 的时候,一般把表单参数放 URL,多个参数用一个 & 与号连接;POST 的时候,把表单参数放 send() 函数中,多个参数同样用 & 与号连接。
运行效果:
服务端 python Flask 代码:
from flask import Flask, jsonify, request
app = Flask(__name__)
#测试 get
@app.route('/text', methods=['GET'])
def testGetText():
return 'Get '+request.args.get('arg')
#测试 post
@app.route('/text', methods=['POST'])
def testPostText():
return 'Post '+request.form['arg']
if __name__ == '__main__':
app.run(host='127.0.0.1', port=54321, debug=True)
JSON 数据的传递
我们可以通过网络或者本地文件来获取 JSON 数据,代码如下:
import QtQuick 2.12
ListView {
id: view
spacing: 10
//model:['red','green','blue']
delegate: Rectangle{
width: ListView.view.width
height: 30
color: modelData
}
//请求网络数据
function request() {
let xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if(xhr.readyState === 4) {
print('request DONE',xhr.status);
if(xhr.status === 200){
print(xhr.responseText.toString())
view.model = JSON.parse(xhr.responseText.toString());
}
}
}
xhr.open("POST", "http://127.0.0.1:54321/json");
xhr.setRequestHeader("Content-type", "application/json");
//xhr.send("['red','green','blue','orange','cyan']");
xhr.send(JSON.stringify(['red','green','blue','orange','cyan']));
}
//访问本地文件
function requestLocal() {
let xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if(xhr.readyState === 4) {
print('request DONE',xhr.status);
if(xhr.status === 200){
print(xhr.responseText.toString())
view.model = JSON.parse(xhr.responseText.toString());
}
}
}
//json文件的文本内容,字符串双引号:["red","green","blue"]
xhr.open("GET", "qrc:/localfile.json");
xhr.send();
}
Component.onCompleted: request()
//Component.onCompleted: requestLocal()
}
运行效果:
服务端 python Flask 代码:
from flask import Flask, jsonify, request
app = Flask(__name__)
#测试传 json
@app.route('/json', methods=['POST'])
def testModel():
#return jsonify(['red', 'green', 'blue'])
#request.json 只能够接受方法为POST、Body为raw,header 内容为 application/json类型的数据
return jsonify(request.json)
if __name__ == '__main__':
app.run(host='127.0.0.1', port=54321, debug=True)
简易的封装
有人(参考博客)将 GET/POST 做了简单的封装,可以参考下:
一个 ajax.js 文件:
// GET
function get(url, success, failure)
{
var xhr = new XMLHttpRequest;
xhr.open("GET", url);
xhr.onreadystatechange = function() {
handleResponse(xhr, success, failure);
}
xhr.send();
}
// POST
function post(url, arg, success, failure)
{
var xhr = new XMLHttpRequest;
xhr.open("POST", url);
xhr.setRequestHeader("Content-Length", arg.length);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;"); //用POST的时候一定要有这句
xhr.onreadystatechange = function() {
handleResponse(xhr, success, failure);
}
xhr.send(arg);
}
// 处理返回值
function handleResponse(xhr, success, failure){
if (xhr.readyState == XMLHttpRequest.DONE) {
if (xhr.status == 200){
if (success != null && success != undefined)
{
var result = xhr.responseText;
try{
success(result, JSON.parse(result));
}catch(e){
success(result, {});
}
}
}
else{
if (failure != null && failure != undefined)
failure(xhr.responseText, xhr.status);
}
}
}
基本使用:
import QtQuick 2.12
import QtQuick.Controls 2.12
Window {
id: window
visible: true
width: 640
height: 480
title: qsTr("QML && AJAX")
// ... ...
function testGet(){
Ajax.get("http://这里填网址.com?带好参数哦",
function(result, json){ //成功后的回调函数
console.log(result) //结果
console.log(json) //结果的Json
},function (){ //失败后的回调函数
console.log("error")
}
);
}
function testPost(){
Ajax.post("http://这里填api网址","参数名 = 参数内容",
function(result, json){ //成功后的回调函数
console.log(result) //结果
console.log(json) //结果的Json
},function (){ //失败后的回调函数
console.log("error")
}
)
}
}
参考
书籍:QmlBook
博客:https://blog.csdn.net/keysking/article/details/79920597