Attention: Here be dragons
This is the latest
(unstable) version of this documentation, which may document features
not available in or compatible with released stable versions of Godot.
Checking the stable version of the documentation...
HTTPRequest
具有发送 HTTP(S) 请求能力的节点。
描述
一个具备发送 HTTP 请求能力的节点。它在内部使用了 HTTPClient。
可用于发起 HTTP 请求,例如通过 HTTP 下载或上传文件及网页内容。
警告: 关于各种限制(尤其是 TLS 安全性方面),请参阅 HTTPClient 上的相关说明和警告。
注意: 导出到 Android 平台时,请务必在导出项目或使用一键部署之前,在 Android 导出预设中启用 INTERNET(网络访问)权限。否则,Android 系统会拦截任何形式的网络通信。
示例: 调用一个 REST API 并打印其返回的其中一个字段:
func _ready():
# 创建一个 HTTP 请求节点,并连接它的完成信号。
var http_request = HTTPRequest.new()
add_child(http_request)
http_request.request_completed.connect(self._http_request_completed)
# 执行一个 GET 请求。编写(这段代码)时,下方的 URL 会返回 JSON 格式的数据。
var error = http_request.request("https://httpbin.org/get")
if error != OK:
push_error("An error occurred in the HTTP request.")
# 执行一个 POST 请求。编写(这段代码)时,下方的 URL 会返回 JSON 格式的数据。
# 注意:不要使用单个 HTTPRequest 节点同时发起多个请求。
# 下面提供的代码片段仅供参考。
var body = JSON.stringify({"name": "Godette"})
error = http_request.request("https://httpbin.org/post", [], HTTPClient.METHOD_POST, body)
if error != OK:
push_error("An error occurred in the HTTP request.")
# 当 HTTP 请求完成时被调用。
func _http_request_completed(result, response_code, headers, body):
var json = JSON.new()
json.parse(body.get_string_from_utf8())
var response = json.get_data()
# 将打印出 HTTPRequest 节点所使用的用户代理字符串(该字符串由 httpbin.org 识别)。
print(response.headers["User-Agent"])
public override void _Ready()
{
// 创建一个 HTTP 请求节点,并连接它的完成信号。
var httpRequest = new HttpRequest();
AddChild(httpRequest);
httpRequest.RequestCompleted += HttpRequestCompleted;
// 执行一个 GET 请求。编写(这段代码)时,下方的 URL 会返回 JSON 格式的数据。
Error error = httpRequest.Request("https://httpbin.org/get");
if (error != Error.Ok)
{
GD.PushError("An error occurred in the HTTP request.");
}
// 执行一个 POST 请求。编写(这段代码)时,下方的 URL 会返回 JSON 格式的数据。
// 注意:不要使用单个 HTTPRequest 节点同时发起多个请求。
// 下面提供的代码片段仅供参考。
string body = Json.Stringify(new Godot.Collections.Dictionary
{
{ "name", "Godette" }
});
error = httpRequest.Request("https://httpbin.org/post", null, HttpClient.Method.Post, body);
if (error != Error.Ok)
{
GD.PushError("An error occurred in the HTTP request.");
}
}
// 在 HTTP 请求完成时被调用。
private void HttpRequestCompleted(long result, long responseCode, string[] headers, byte[] body)
{
var json = new Json();
json.Parse(body.GetStringFromUtf8());
var response = json.GetData().AsGodotDictionary();
// 将打印出 HTTPRequest 节点所使用的用户代理字符串(该字符串由 httpbin.org 识别)。
GD.Print((response["headers"].AsGodotDictionary())["User-Agent"]);
}
示例: 使用 HTTPRequest 加载一张图片并显示它:
func _ready():
# 创建一个 HTTP 请求节点,并连接它的完成信号。
var http_request = HTTPRequest.new()
add_child(http_request)
http_request.request_completed.connect(self._http_request_completed)
# 执行 HTTP 请求。编写(这段代码)时,下方的 URL 会返回一张 PNG 格式的图片。
var error = http_request.request("https://placehold.co/512.png")
if error != OK:
push_error("An error occurred in the HTTP request.")
# 当 HTTP 请求完成时被调用。
func _http_request_completed(result, response_code, headers, body):
if result != HTTPRequest.RESULT_SUCCESS:
push_error("Image couldn't be downloaded. Try a different image.")
var image = Image.new()
var error = image.load_png_from_buffer(body)
if error != OK:
push_error("Couldn't load the image.")
var texture = ImageTexture.create_from_image(image)
# 在 TextureRect 节点中显示这张图片。
var texture_rect = TextureRect.new()
add_child(texture_rect)
texture_rect.texture = texture
public override void _Ready()
{
// 创建一个 HTTP 请求节点,并连接它的完成信号。
var httpRequest = new HttpRequest();
AddChild(httpRequest);
httpRequest.RequestCompleted += HttpRequestCompleted;
// 执行 HTTP 请求。在编写(这段代码)时,下方的 URL 会返回一张 PNG 格式的图片。
Error error = httpRequest.Request("https://placehold.co/512.png");
if (error != Error.Ok)
{
GD.PushError("An error occurred in the HTTP request.");
}
}
// 当 HTTP 请求完成时被调用。
private void HttpRequestCompleted(long result, long responseCode, string[] headers, byte[] body)
{
if (result != (long)HttpRequest.Result.Success)
{
GD.PushError("Image couldn't be downloaded. Try a different image.");
}
var image = new Image();
Error error = image.LoadPngFromBuffer(body);
if (error != Error.Ok)
{
GD.PushError("Couldn't load the image.");
}
var texture = ImageTexture.CreateFromImage(image);
// 在 TextureRect 节点中显示这张图片。
var textureRect = new TextureRect();
AddChild(textureRect);
textureRect.Texture = texture;
}
注意: HTTPRequest 节点会自动处理响应体(response bodies)的解压缩。除非你已经手动指定了,否则引擎会自动为你发出的每一个请求添加一个 Accept-Encoding 请求头。因此,任何带有 Content-Encoding: gzip 响应头的返回数据,都会被自动解压缩,并以未压缩的字节形式直接交给你。
教程
属性
|
||
|
||
|
||
|
||
|
||
|
||
|
方法
void |
|
get_body_size() const |
|
get_downloaded_bytes() const |
|
get_http_client_status() const |
|
request(url: String, custom_headers: PackedStringArray = PackedStringArray(), method: Method = 0, request_data: String = "") |
|
request_raw(url: String, custom_headers: PackedStringArray = PackedStringArray(), method: Method = 0, request_data_raw: PackedByteArray = PackedByteArray()) |
|
void |
set_http_proxy(host: String, port: int) |
void |
set_https_proxy(host: String, port: int) |
void |
set_tls_options(client_options: TLSOptions) |
信号
request_completed(result: int, response_code: int, headers: PackedStringArray, body: PackedByteArray) 🔗
请求完成时触发。
枚举
enum Result: 🔗
Result RESULT_SUCCESS = 0
请求成功。
Result RESULT_CHUNKED_BODY_SIZE_MISMATCH = 1
请求失败,传输的实际数据块大小与预期不符。可能的原因有网络错误、服务器配置问题、数据块编码问题等。
Result RESULT_CANT_CONNECT = 2
连接时请求失败。
Result RESULT_CANT_RESOLVE = 3
解析时请求失败。
Result RESULT_CONNECTION_ERROR = 4
因连接(读写)错误而失败。
Result RESULT_TLS_HANDSHAKE_ERROR = 5
TLS 握手时请求失败。
Result RESULT_NO_RESPONSE = 6
请求(目前还)没有获得相应。
Result RESULT_BODY_SIZE_LIMIT_EXCEEDED = 7
请求超出了大小上限,见 body_size_limit。
Result RESULT_BODY_DECOMPRESS_FAILED = 8
请求失败,解压响应体出错。可能的原因有压缩格式不支持、压缩格式错误、数据损坏、传输不完整等。
Result RESULT_REQUEST_FAILED = 9
请求失败(目前未使用)。
Result RESULT_DOWNLOAD_FILE_CANT_OPEN = 10
HTTPRequest 无法打开下载文件。
Result RESULT_DOWNLOAD_FILE_WRITE_ERROR = 11
HTTPRequest 无法写入下载文件。
Result RESULT_REDIRECT_LIMIT_REACHED = 12
请求超出了重定向次数上限,见 max_redirects。
Result RESULT_TIMEOUT = 13
请求由于超时而失败。如果本就希望请求花费较长的时间,请尝试增大 timeout,或将其设为 0.0 从而完全移除超时。
属性说明
如果为 true,这个报头会被添加到每个请求中:Accept-Encoding: gzip, deflate 告诉服务器可以压缩响应正文。
任何声明 gzip 或 deflate 的 Content-Encoding 的响应正文,将被自动解压缩,并且未压缩的字节将通过 request_completed 被传递。
如果用户指定了自己的 Accept-Encoding 报头,那么无论 accept_gzip 是什么,都不会添加任何报头。
如果为 false,这将不会添加报头,并且不会对响应正文执行任何解压缩。响应正文的原始字节将通过 request_completed 返回。
响应正文的最大允许大小。如果响应正文被压缩,这将用作解压缩的正文的最大允许大小。
int download_chunk_size = 65536 🔗
使用的缓冲区大小和每次迭代读取的最大字节数。参阅 HTTPClient.read_chunk_size。
下载小文件时将其设置为较低的值,以降低内存使用量,但会降低下载速度,例如 4096 表示 4 KiB。
要下载到的文件。将任何接收到的文件输出到其中。
允许的最大重定向数。
请求超时前的等待时间,单位为秒(与 Engine.time_scale 无关)。如果 timeout 为 0.0,则请求将永远不会超时。
对于简单的请求,例如与 REST API 通信,建议将 timeout 设为与服务器响应时间匹配的值(通常在 1.0 到 10.0 之间)。这将有助于防止由于响应时间波动而导致的不必要的超时,同时仍然允许应用程序检测请求何时超时。对于较大的请求,例如文件下载,建议将 timeout 设置为 0.0,禁用超时功能。这将有助于防止由于超出超时值而导致大型传输失败。
为 true 时,将启用多线程提高性能。
方法说明
void cancel_request() 🔗
取消当前请求。
返回响应体长度。
注意:部分 Web 服务器可能不发送响应体长度,此时返回值将为 -1。如果使用分块传输编码,响应体的长度也将为 -1。
int get_downloaded_bytes() const 🔗
返回该 HTTPRequest 已下载的字节数。
Status get_http_client_status() const 🔗
返回内部 HTTPClient 的当前状态。
Error request(url: String, custom_headers: PackedStringArray = PackedStringArray(), method: Method = 0, request_data: String = "") 🔗
在底层的 HTTPClient 上创建请求。如果没有配置错误,它会尝试使用 HTTPClient.connect_to_host() 连接并将参数传递给 HTTPClient.request()。
如果成功创建请求,则返回 @GlobalScope.OK。(并不意味着服务器已响应),如果不在树中,则返回 @GlobalScope.ERR_UNCONFIGURED;如果仍在处理先前的请求,则返回 @GlobalScope.ERR_BUSY;如果给定的字符串不是有效的 URL 格式,则返回 @GlobalScope.ERR_INVALID_PARAMETER;或者如果不使用线程并且 HTTPClient 无法连接到主机,则返回 @GlobalScope.ERR_CANT_CONNECT。
注意:当 method 为 HTTPClient.METHOD_GET 时,通过 request_data 发送的有效载荷可能会被服务器忽略,甚至导致服务器拒绝请求(见 RFC 7231 第 4.3.1 节了解更多详情)。作为一种变通方法,可以在 URL 中将数据作为查询字符串发送(有关示例,请参见 String.uri_encode())。
注意:建议使用传输加密(TLS)并避免在 HTTP GET URL 参数中发送敏感信息(例如登录凭据)。考虑改用 HTTP POST 请求或 HTTP 报头来获取此类信息。
Error request_raw(url: String, custom_headers: PackedStringArray = PackedStringArray(), method: Method = 0, request_data_raw: PackedByteArray = PackedByteArray()) 🔗
在底层的HTTPClient上创建请求,使用一个原始字节数组作为请求主体。如果没有配置错误,它会尝试使用 HTTPClient.connect_to_host() 连接并将参数传递给 HTTPClient.request()。
如果请求创建成功,则返回 @GlobalScope.OK。(并不意味着服务器已响应),@GlobalScope.ERR_UNCONFIGURED 如果不在树中,@GlobalScope.ERR_BUSY 如果仍在处理先前的请求,@GlobalScope.ERR_INVALID_PARAMETER 如果给定的字符串不是有效的 URL 格式,或 @GlobalScope.ERR_CANT_CONNECT如果不使用线程并且 HTTPClient 无法连接到主机。
void set_http_proxy(host: String, port: int) 🔗
设置 HTTP 请求使用的代理服务器。
如果 host 为空或者 port 为 -1,则会取消设置代理服务器。
void set_https_proxy(host: String, port: int) 🔗
设置 HTTPS 请求使用的代理服务器。
如果 host 为空或者 port 为 -1,则会取消设置代理服务器。
void set_tls_options(client_options: TLSOptions) 🔗
设置连接到 HTTPS 服务器时使用的 TLSOptions。见 TLSOptions.client()。