From caf1f11371869b639469c961c6b4747f87fe1c76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=80=9D=E6=B5=B7?= <1464576565@qq.com> Date: Wed, 23 Apr 2025 13:50:17 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Runtime/Utility/Utility.Http.cs | 136 ++++++++++++++------------------ 1 file changed, 59 insertions(+), 77 deletions(-) diff --git a/Runtime/Utility/Utility.Http.cs b/Runtime/Utility/Utility.Http.cs index 8773412..8f41242 100644 --- a/Runtime/Utility/Utility.Http.cs +++ b/Runtime/Utility/Utility.Http.cs @@ -9,105 +9,87 @@ namespace AlicizaX { public static partial class Utility { - /// - /// Http 相关的实用函数。 - /// public static partial class Http { /// - /// GET请求与获取结果。 + /// 发送 GET 请求 /// - /// 网络URL。 - /// 超时时间。 - /// 请求结果。 public static async UniTask Get(string url, float timeout = 5f) { - var cts = new CancellationTokenSource(); - cts.CancelAfterSlim(TimeSpan.FromSeconds(timeout)); - - using UnityWebRequest unityWebRequest = UnityWebRequest.Get(url); - return await SendWebRequest(unityWebRequest, cts); + using var cts = CreateTimeoutTokenSource(timeout); + using var request = UnityWebRequest.Get(url); + return await SendRequest(request, cts.Token); } /// - /// Post请求与获取结果. + /// 发送 JSON 格式的 POST 请求(服务端需用 [FromBody] 接收) /// - /// 网络URL。 - /// Post数据。 - /// 超时时间。 - /// 请求结果。 - public static async UniTask Post(string url, string postData, float timeout = 5f) + public static async UniTask PostJson(string url, object jsonData, float timeout = 5f) + { + using var cts = CreateTimeoutTokenSource(timeout); + var json = JsonUtility.ToJson(jsonData); + using var request = CreateJsonPostRequest(url, json); + return await SendRequest(request, cts.Token); + } + + /// + /// 发送表单格式的 POST 请求(x-www-form-urlencoded) + /// + public static async UniTask PostForm(string url, Dictionary formData, float timeout = 5f) + { + using var cts = CreateTimeoutTokenSource(timeout); + using var request = UnityWebRequest.Post(url, formData); + return await SendRequest(request, cts.Token); + } + + /// + /// 发送多部分表单的 POST 请求(multipart/form-data,支持文件上传) + /// + public static async UniTask PostMultipart(string url, WWWForm formData, float timeout = 5f) + { + using var cts = CreateTimeoutTokenSource(timeout); + using var request = UnityWebRequest.Post(url, formData); + return await SendRequest(request, cts.Token); + } + + //----- 私有工具方法 ----- + private static CancellationTokenSource CreateTimeoutTokenSource(float timeout) { var cts = new CancellationTokenSource(); cts.CancelAfterSlim(TimeSpan.FromSeconds(timeout)); - - using UnityWebRequest unityWebRequest = UnityWebRequest.PostWwwForm(url, postData); - return await SendWebRequest(unityWebRequest, cts); + return cts; } - /// - /// Post请求与获取结果. - /// - /// 网络URL。 - /// Post数据。 - /// 超时时间。 - /// 请求结果。 - public static async UniTask Post(string url, Dictionary formFields, float timeout = 5f) + private static UnityWebRequest CreateJsonPostRequest(string url, string json) { - var cts = new CancellationTokenSource(); - cts.CancelAfterSlim(TimeSpan.FromSeconds(timeout)); - - using UnityWebRequest unityWebRequest = UnityWebRequest.Post(url, formFields); - return await SendWebRequest(unityWebRequest, cts); + // 手动处理 JSON(Unity 未提供直接方法) + var request = new UnityWebRequest(url, "POST"); + byte[] jsonBytes = System.Text.Encoding.UTF8.GetBytes(json); + request.uploadHandler = new UploadHandlerRaw(jsonBytes); + request.downloadHandler = new DownloadHandlerBuffer(); + request.SetRequestHeader("Content-Type", "application/json"); + return request; } - /// - /// Post请求与获取结果. - /// - /// 网络URL。 - /// Post数据。 - /// 超时时间。 - /// 请求结果。 - public static async UniTask Post(string url, WWWForm formData, float timeout = 5f) - { - var cts = new CancellationTokenSource(); - cts.CancelAfterSlim(TimeSpan.FromSeconds(timeout)); - - using UnityWebRequest unityWebRequest = UnityWebRequest.Post(url, formData); - return await SendWebRequest(unityWebRequest, cts); - } - - /// - /// 抛出网络请求。 - /// - /// UnityWebRequest。 - /// CancellationTokenSource。 - /// 请求结果。 - public static async UniTask SendWebRequest(UnityWebRequest unityWebRequest, CancellationTokenSource cts) + private static async UniTask SendRequest(UnityWebRequest request, CancellationToken token) { try { - var (isCanceled, _) = await unityWebRequest.SendWebRequest().WithCancellation(cts.Token).SuppressCancellationThrow(); - if (isCanceled) - { - Log.Warning($"HttpPost {unityWebRequest.url} be canceled!"); - unityWebRequest.Dispose(); - return string.Empty; - } - } - catch (OperationCanceledException ex) - { - if (ex.CancellationToken == cts.Token) - { - Log.Warning("HttpPost Timeout"); - unityWebRequest.Dispose(); - return string.Empty; - } - } + await request.SendWebRequest().WithCancellation(token); - string ret = unityWebRequest.downloadHandler.text; - unityWebRequest.Dispose(); - return ret; + if (request.result != UnityWebRequest.Result.Success) + { + Debug.LogError($"HTTP Error ({request.responseCode}): {request.error}"); + return string.Empty; + } + + return request.downloadHandler.text; + } + catch (OperationCanceledException) when (token.IsCancellationRequested) + { + Debug.LogWarning("Request timed out."); + return string.Empty; + } } } }