Godot provides two classes, HTTPClient and HTTPRequest, for HTTP requests. Their differences are:
- The HTTP client is the bottom layer, and needs to be returned by the server itself; HTTPRequest only needs to send a request, and the corresponding signal will be triggered when the server data is returned
- HTTPClient does not need to be added to the node of the scene tree, while HTTPRequest inherits from the Note class and must be added to the node to function normally
Considering that I am not very familiar with the underlying things, and since I use HTTP requests, I do not need a large number of requests, so I directly use the officially encapsulated HTTPRequest class.
I wrote the first example by referring directly to the example provided by the official.
Ajax.gd
var HttpObject : HTTPRequest #Class initialization func _init(): # Create an HTTP request node and connect the completion signal. HttpObject = HTTPRequest.new() HttpObject.connect("request_completed", self, "_http_request_completed") #Execute get request func Get(url): var error = HttpObject.request(url) if error != OK: push_error("HTTP An error occurred in the request.") #Request success signal func _http_request_completed(result, response_code, headers, body): if result == 0 and response_code == 200: #Get the complete data returned var response = parse_json(body.get_string_from_utf8()) print(response)
Since I have a global singleton Global.gd, I instantiate this class directly in Global.gd:
var Ajax var _ajaxClass = preload("res://script/network/Ajax.gd") # First load func _ready(): Ajax = _ajaxClass.new() add_child(Ajax.HttpObject) #The node must be added before it can be used normally, otherwise an error will be reported Ajax.Get("http://127.0.0.1:8000/")
After testing, the server data can be returned normally, but then a problem is found, that is, the session saved by the server has no effect, but it is good to test it directly in the browser, which indicates that it is not a server problem.
Because the ajax classes used by js in the past were all encapsulated by others, I have a very shallow understanding of the underlying http. Later, I opened F12 in the browser to test, and found that every time the server returned a cookie in the header, and every time I made a request, I carried the cookie that was sent last time in the header.
So I modified Ajax.gd
var _cookie : String func _init(): _cookie = "0" # Create an HTTP request node and connect the completion signal. HttpObject = HTTPRequest.new() HttpObject.connect("request_completed", self, "_http_request_completed") #Execute get request func Get(url): var h = [ "cookie: %s" % _cookie ] var error = HttpObject.request(url, h) if error != OK: push_error("HTTP An error occurred in the request.") #Request success signal func _http_request_completed(result, response_code, headers, body): if result == 0 and response_code == 200: #Get the complete data returned var response = parse_json(body.get_string_from_utf8()) print(response) #Get the cookie of the next request for s in headers: if s.left(11) == "set-cookie:": s = s.substr(12) s = s.split(";")[0] _cookie = s break
After testing, it was found that the server session was normal, and the problems such as the login account were solved. However, there was still one problem that was not solved, that is, if the last request sent was not returned, it would be ignored when sending the request.
I didn't know what a good way to do this, so I wrote a request queue myself, and then made a request when the last request had a result.
By the way, change the Get method, pass a request address and parameter list, and then assemble it.
The successful request print is also changed to signal:
#cookie information var _cookie : String #Request queue var _queue = [] #Is it in the get request var _isGeting = false var HttpObject : HTTPRequest #Request success signal signal onResponse(model, body) #Class initialization func _init(): _cookie = "0" # Create an HTTP request node and connect the completion signal. HttpObject = HTTPRequest.new() HttpObject.connect("request_completed", self, "_http_request_completed") # Send request func Send(model, body = {}): var url = "http://127.0.0.1:8000/" #Whether to include model if model != "": url = "%s%s" % [url, model] #Composition parameters 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() # Check whether the request needs to be sent 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 An error occurred in the request.") # Request succeeded func _http_request_completed(result, response_code, headers, body): if result == 0 and response_code == 200: #Get the complete data returned var response = parse_json(body.get_string_from_utf8()) #Trigger event signal emit_signal("onResponse", _queue[0]["m"], response) #Delete successfully requested elements _queue.remove(0) #Get the cookie of the next request for s in headers: if s.left(11) == "set-cookie:": s = s.substr(12) s = s.split(";")[0] _cookie = s break else: push_error("Request network address %s Failed!" % _queue[0]["u"]) _isGeting = false _CheckSend()
Calling method:
Ajax.Send("get")
Ajax.Send("register", {"user" : "nazgul", "pswd" : "123456"})