Godot提供了HTTPClient和HTTPRequest两个类来进行HTTP请求,它们的区别在于:
考虑到自己对底层的东西并不是很熟,而且既然使用HTTP请求,就是因为并不需要很大的请求量,所以就直接使用官方封装好的HTTPRequest类。
我直接参考了官方提供的例子来写了第一个实例。
Ajax.gd
var HttpObject : HTTPRequest
#类初始化
func _init():
# 创建 HTTP 请求节点并连接完成信号。
HttpObject = HTTPRequest.new()
HttpObject.connect("request_completed", self, "_http_request_completed")
#执行get请求
func Get(url):
var error = HttpObject.request(url)
if error != OK:
push_error("HTTP 请求发生了错误。")
#请求成功信号
func _http_request_completed(result, response_code, headers, body):
if result == 0 and response_code == 200:
#获得返回的完整数据
var response = parse_json(body.get_string_from_utf8())
print(response)
由于我有一个全局单例Global.gd,所以我直接在Global.gd里实例化这个类:
var Ajax
var _ajaxClass = preload("res://script/network/Ajax.gd")
# 首次载入
func _ready():
Ajax = _ajaxClass.new()
add_child(Ajax.HttpObject) #必须加入节点才能正常使用,否则会报错
Ajax.Get("http://127.0.0.1:8000/")
经测试可以正常返回服务器数据,但随后发现了问题,即服务器保存的session没有效果,而直接在浏览器测试是好的,说明不是服务器问题。
由于以前js用的ajax类都是别人封装好的,所以对http的底层了解很浅。后来在浏览器中开着F12测试,发现每次服务器返回的标头中都下发了cookie,而每次请求时,在标头中带上上次下发的cookie。
于是改装了一下Ajax.gd
var _cookie : String
func _init():
_cookie = "0"
# 创建 HTTP 请求节点并连接完成信号。
HttpObject = HTTPRequest.new()
HttpObject.connect("request_completed", self, "_http_request_completed")
#执行get请求
func Get(url):
var h = [
"cookie: %s" % _cookie
]
var error = HttpObject.request(url, h)
if error != OK:
push_error("HTTP 请求发生了错误。")
#请求成功信号
func _http_request_completed(result, response_code, headers, body):
if result == 0 and response_code == 200:
#获得返回的完整数据
var response = parse_json(body.get_string_from_utf8())
print(response)
#获得下一次请求的cookie
for s in headers:
if s.left(11) == "set-cookie:":
s = s.substr(12)
s = s.split(";")[0]
_cookie = s
break
经测试发现服务器session正常了,登陆账号之类的问题就解决了,但是还有一个问题未解决,就是当上一次发送的请求如果还没有返回,此时发送请求时会被忽略。
不知道这个有什么好的办法,于是自己写了一个请求队列,等上次的请求有结果了,再进行请求。
顺便把Get方法改了一下,传一个请求地址与参数列表,再进行组装。
请求成功的print也改成了信号:
#cookie信息
var _cookie : String
#请求队列
var _queue = []
#是否正在get请求中
var _isGeting = false
var HttpObject : HTTPRequest
#请求成功信号
signal onResponse(model, body)
#类初始化
func _init():
_cookie = "0"
# 创建 HTTP 请求节点并连接完成信号。
HttpObject = HTTPRequest.new()
HttpObject.connect("request_completed", self, "_http_request_completed")
# 发送请求
func Send(model, body = {}):
var url = "http://127.0.0.1:8000/"
#是否包含model
if model != "":
url = "%s%s" % [url, model]
#组成参数
var qy = ""
for k in body.keys():
if qy != "":
qy = "%s&" % qy
qy = "%s%s=%s" % [qy, k, body[k].http_escape()]
if qy != "":
url = "%s?%s" % [url, qy]
_queue.append({"m" : model, "u" : url})
_CheckSend()
# 检查是否需要发送请求
func _CheckSend():
if _queue.size() == 0:
return
if _isGeting:
return
_isGeting = true
var h = [
"cookie: %s" % _cookie
]
var url = _queue[0]["u"]
print(url)
var error = HttpObject.request(url, h)
if error != OK:
push_error("HTTP 请求发生了错误。")
# 请求成功
func _http_request_completed(result, response_code, headers, body):
if result == 0 and response_code == 200:
#获得返回的完整数据
var response = parse_json(body.get_string_from_utf8())
#触发事件信号
emit_signal("onResponse", _queue[0]["m"], response)
#删除已请求成功的元素
_queue.remove(0)
#获得下一次请求的cookie
for s in headers:
if s.left(11) == "set-cookie:":
s = s.substr(12)
s = s.split(";")[0]
_cookie = s
break
else:
push_error("请求网络地址 %s 失败!" % _queue[0]["u"])
_isGeting = false
_CheckSend()
调用方法:
Ajax.Send("get")
Ajax.Send("register", {"user" : "nazgul", "pswd" : "123456"})