HTTPRequest

继承: Item < Object

能够发送HTTP(S)请求的节点。

描述

能够发送HTTP请求的节点。在内部使用HTTPClient

可用于发出HTTP请求,即通过HTTP下载或上传文件或Web内容。

警告:有关限制,尤其是有关TLS安全性的限制,请参阅HTTPClient上的注释和警告。

注意:导出到Android时,请确保在导出项目或使用一键部署之前启用Android导出预设中的INTERNET权限。否则,任何形式的网络通信都将被Android阻止。

示例:连接一个REST API并输出其返回的字段之一:

func iStart() -> void:
    # 创建一个 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.new().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"])

示例:使用 HTTPRequest 加载图像并显示它:

func iStart() -> void:
    # 创建一个 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")
    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)

    # Display the image in a TextureRect node.
    var texture_rect = TextureRect.new()
    add_child(texture_rect)
    texture_rect.texture = texture

注意: HTTPRequest节点将自动处理响应体的解压缩。一个Accept-Encoding标头将自动添加到您的每个请求中,除非已经指定了其他标头。任何带有Content-Encoding: gzip标头的响应将自动被解压缩并以未压缩的字节形式发送给您。

属性

方法

void

cancel_request()

int

get_body_size() const

int

get_downloaded_bytes() const

Status

get_http_client_status() const

Error

request(url: String, custom_headers: PackedStringArray = PackedStringArray(), method: Method = 0, request_data: String = "")

Error

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以完全删除超时。


属性说明

bool accept_gzip = true 🔗

  • void set_accept_gzip(value: bool)

  • bool is_accepting_gzip()

如果true,则将此标头添加到每个请求中:Accept-Encode: gzip,😍ate告诉服务器可以压缩响应正文。

任何声明内容编码gzip😍ate的Response主体将被自动解压缩,未压缩的字节将通过request_completed传递。

如果用户指定了自己的Accept-Encode标头,则无论accept_gzip如何,都不会添加标头。

如果false,则不会添加标头,也不会对响应体进行解压。响应体的原始字节将通过request_completed返回。


int body_size_limit = -1 🔗

  • void set_body_size_limit(value: int)

  • int get_body_size_limit()

响应正文的最大允许大小。如果响应正文被压缩,这将用作解压缩正文的最大允许大小。


int download_chunk_size = 65536 🔗

  • void set_download_chunk_size(value: int)

  • int get_download_chunk_size()

使用的缓冲区大小和每次迭代要读取的最大字节数。参见HTTPClient.read_chunk_size

下载小文件时将其设置为较低的值(例如4 KiB为4096),以降低下载速度为代价来减少内存使用。


String download_file = "" 🔗

  • void set_download_file(value: String)

  • String get_download_file()

要下载到的文件。将任何接收到的文件输出到其中。


int max_redirects = 8 🔗

  • void set_max_redirects(value: int)

  • int get_max_redirects()

允许的最大重定向数。


float timeout = 0.0 🔗

  • void set_timeout(value: float)

  • float get_timeout()

在请求超时之前等待的时间(以秒为单位)。如果timeout设置为0.0,则请求永远不会超时。对于简单的请求,例如与REST API通信,建议将timeout设置为适合服务器响应时间的值(例如1.010.0之间)。这将有助于防止服务器响应时间变化导致的不必要超时,同时仍然允许应用程序检测请求何时超时。对于较大的请求,例如文件下载,建议将timeout设置为0.0,从而禁用超时功能。这将有助于防止由于超过超时值而导致的大型传输失败。


bool use_threads = false 🔗

  • void set_use_threads(value: bool)

  • bool is_using_threads()

如果true,则使用多线程来提高性能。


方法说明

void cancel_request() 🔗

取消当前请求。


int get_body_size() const 🔗

返回响应正文长度。

注意:某些Web服务器可能不会发送正文长度。在这种情况下,返回的值将是-1。如果使用分块传输编码,正文长度也将是-1


int get_downloaded_bytes() const 🔗

返回此HTTPRequest下载的字节数。


Status get_http_client_status() const 🔗

返回底层HTTPClient的当前状态。请参阅Status


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如果仍在处理先前的请求,@GlobalScope.ERR_INVALID_PARAMETER如果给定的字符串不是有效的URL格式,或者@GlobalScope.ERR_CANT_CONNECT如果不使用线程并且HTTPClient无法连接到主机。

注意:methodHTTPClient.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()