How does one perform an http POST request? Documentation is unclear.

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By johnygames

I’ve been trying to perform a simple request from various sites but so far I’ve had no success. I used the example at the http request section of the docs, but I still can’t retrieve the results I want. More specifically I tried the following:

extends Node2D
onready var http= $HTTPRequest # get the httprequest node
var url = "http://bark.phon.ioc.ee/punctuator/" # the url I am trying to retrieve info from

func _ready():
	pass


func _on_Button_pressed():
	_make_post_request(url, ["text:this is a test"], false)


func _on_HTTPRequest_request_completed(result, response_code, headers, body):
	var json = JSON.parse(body.get_string_from_utf8())
	print(json.result)

func _make_post_request(url, data_to_send, use_ssl):
	# Convert data to json string:
	var query= JSON.print(data_to_send)
	# Add 'Content-Type' header:
	var headers = ["Content-Type: application/json"]
	http.request(url, headers, use_ssl, HTTPClient.METHOD_POST, query)

I don’t understand how I am supposed to get results from this. What do I include in the data_to_send variable? A list? A dictionary? And what format should I put it in?
Lastly, how do I print the result?

Sidenote: I was able to make this work using Python and the requests module in particular. I used a POST request and it fetched the data I wanted.

:bust_in_silhouette: Reply From: rakkarage

some of the relevant code from where i got it working

func signIn(http: HTTPRequest, email: String, password: String) -> Array:
	var body := { "email": email, "password": password, "returnSecureToken": true }
	http.request(_signInUrl % _apiKey, [], false, HTTPClient.METHOD_POST, to_json(body))
	return yield(http, "request_completed")
...
var response = yield(Firebase.signIn(_http, email, password), "completed")
...
func _getResult(response: Array) -> Dictionary:
	return JSON.parse(response[3].get_string_from_utf8()).result

yield on request_completed to finish the call
this will return a response array check that element[1] == 200

response[1] == 200

then you can parse the element[3] to get result from response if was 200
ya kinda confusing but i got it working here:

Thank you for posting your code! However, I still struggle to understand how to adapt it to my case. Your example seems to pertain specifically to Firebase and it applies to cases where you want to enter a password and an email. How can I adapt this to my situation, where all I am trying to do is fetch data from a site? What form should my query be in? I tried the last line of your code:

return JSON.parse(response[3].get_string_from_utf8()).result

but it threw a Nonexistent Function error. Then I tried replacing get_string_from_utf8 with to_string() but it returns Null.

johnygames | 2020-07-08 22:18

a call to HTTPRequest returns a piece of json/html on all platforms and computers
i am not sure of the format exactly but it is a standard html response… the [2] is the code

ONLY if code is 200 (the call succeeded) will the response[3] have what you want

if response[2] == 200:
print(JSON.parse(response[3].get_string_from_utf8()).result)

sorry i could not be more helpful print(response) etc can help

rakkarage | 2020-07-08 22:59

what version if not have get_string_from_utf8? thanks

rakkarage | 2020-07-08 23:03

I am using version 3.2 stable. I probably tried to call the method on the wrong node.

johnygames | 2020-07-09 08:49