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.

HTTPRequest

继承: Node < Object

具有发送 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"])

示例: 使用 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

注意: HTTPRequest 节点会自动处理响应体(response bodies)的解压缩。除非你已经手动指定了,否则引擎会自动为你发出的每一个请求添加一个 Accept-Encoding 请求头。因此,任何带有 Content-Encoding: gzip 响应头的返回数据,都会被自动解压缩,并以未压缩的字节形式直接交给你。

教程

属性

bool

accept_gzip

true

int

body_size_limit

-1

int

download_chunk_size

65536

String

download_file

""

int

max_redirects

8

float

timeout

0.0

bool

use_threads

false

方法

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-Encoding: gzip, deflate 告诉服务器可以压缩响应正文。

任何声明 gzipdeflateContent-Encoding 的响应正文,将被自动解压缩,并且未压缩的字节将通过 request_completed 被传递。

如果用户指定了自己的 Accept-Encoding 报头,那么无论 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

下载小文件时将其设置为较低的值,以降低内存使用量,但会降低下载速度,例如 4096 表示 4 KiB。


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()

请求超时前的等待时间,单位为秒(与 Engine.time_scale 无关)。如果 timeout0.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 的当前状态。


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

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