1. 关键代码
1.1 协程实现
using System;
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;
using System.Collections.Generic;
using System.Linq;
using System.Text;
public class WebRequest : MonoBehaviour
{
/// <summary>
/// GET请求
/// </summary>
/// <param name="url">请求地址</param>
/// <param name="callback">请求完成回调</param>
public void Get(string url, Action<bool,byte[]> callback)
{
StartCoroutine(CoroutineGetRequest(url, callback));
}
/// <summary>
/// POST请求
/// </summary>
/// <param name="url">请求地址</param>
/// <param name="postData">上传的数据</param>
/// <param name="customHeaders">自定义请求头</param>
/// <param name="callback">请求完成回调</param>
public void Post(string url, string postData,Dictionary<string, string> customHeaders, Action<bool, byte[]> callback)
{
StartCoroutine(CoroutinePostRequest(url, postData, customHeaders, callback));
}
IEnumerator CoroutineGetRequest(string url,Action<bool,byte[]> callback)
{
// 使用UnityWebRequest发送一个GET请求
using UnityWebRequest request = UnityWebRequest.Get(url);
// 发送请求并等待结果
yield return request.SendWebRequest();
// 判断请求结果是否成功
if (request.result != UnityWebRequest.Result.Success)
{
// 请求不成功,通过回调函数返回失败状态和错误信息
callback?.Invoke(false, Encoding.UTF8.GetBytes(request.error));
}
else
{
// 获取响应消息
byte[] responseMessage = request.downloadHandler.data;
// 调用回调函数并传入true和响应消息
callback?.Invoke(true, responseMessage);
}
}
IEnumerator CoroutinePostRequest(string url, string postData, Dictionary<string, string> requestHeaders, Action<bool, byte[]> callback)
{
using (UnityWebRequest request = new UnityWebRequest(url, "POST"))
{
// 将POST数据转换为字节数组
byte[] bodyRaw = System.Text.Encoding.UTF8.GetBytes(postData);
// 设置上传处理程序为UploadHandlerRaw
request.uploadHandler = new UploadHandlerRaw(bodyRaw);
// 设置下载处理程序为DownloadHandlerBuffer
request.downloadHandler = new DownloadHandlerBuffer();
// 设置请求头的Content-Type
request.SetRequestHeader("Content-Type", "application/json");
// 添加自定义请求头
if (requestHeaders != null)
{
foreach (var header in requestHeaders.Where(h => h.Key.ToLower() != "content-type"))
{
request.SetRequestHeader(header.Key, header.Value);
}
}
// 发送请求并等待结果
yield return request.SendWebRequest();
// 判断请求结果是否成功
if (request.result != UnityWebRequest.Result.Success)
{
// 请求不成功,通过回调函数返回失败状态和错误信息
callback?.Invoke(false, Encoding.UTF8.GetBytes(request.error));
}
else
{
// 请求成功,通过回调函数返回成功状态和响应消息
var responseMessage = request.downloadHandler.data;
callback?.Invoke(true, responseMessage);
}
}
}
}
1.2 异步实现
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
public class AsyncWebRequest
{
#region 异步请求
/// <summary>
/// 异步GET请求
/// </summary>
/// <param name="url"></param>
/// <param name="requestComplete"></param>
/// <returns></returns>
public async void Get(string url, Action<bool, byte[]> requestComplete)
{
var result =await AsyncGetRequest(url);
requestComplete?.Invoke(result.Item1, result.Item2);
}
private static async Task<(bool, byte[])> AsyncGetRequest(string url)
{
var tcs = new TaskCompletionSource<(bool, byte[])>();
HttpClient client = new HttpClient();
try
{
// 发送GET请求获取响应
HttpResponseMessage response = await client.GetAsync(url);
// 如果响应成功
if (response.IsSuccessStatusCode)
{
// 读取响应体并设置结果为true和响应体
byte[] responseBody = await response.Content.ReadAsByteArrayAsync();
tcs.SetResult((true, responseBody));
}
// 如果响应失败
else
{
// 设置结果为false和响应原因
tcs.SetResult((false, null));
Debug.LogError("请求失败");
}
}
// 捕获所有异常并设置结果为false和异常消息
catch (Exception ex)
{
Debug.LogError(ex);
tcs.SetResult((false, null));
}
// 不管是否发生异常,最后都释放 HttpClient 的资源
finally
{
client.Dispose();
}
// 返回异步任务的结果
return await tcs.Task;
}
/// <summary>
/// 异步POST请求
/// </summary>
/// <param name="url"></param>
/// <param name="postData"></param>
/// <param name="customHeaders"></param>
/// <param name="requestComplete"></param>
public async void Post(string url, string postData, Dictionary<string, string> customHeaders, Action<bool, byte[]> requestComplete = null)
{
var result = await AsyncPostRequest(url, postData, customHeaders);
requestComplete?.Invoke(result.Item1, result.Item2);
}
private async Task<(bool, byte[])> AsyncPostRequest(string url, string postData, Dictionary<string, string> requestHeaders)
{
var tcs = new TaskCompletionSource<(bool, byte[])>();
using (HttpClient client = new HttpClient())
{
try
{
// 创建StringContent对象时,显式设置Content-Type
StringContent content = new StringContent(postData, Encoding.UTF8, "application/json");
// 添加额外的请求头,但排除Content-Type
if (requestHeaders != null)
{
foreach (var header in requestHeaders.Where(h => h.Key.ToLower() != "content-type"))
{
client.DefaultRequestHeaders.Add(header.Key, header.Value);
}
}
// 发送POST请求
HttpResponseMessage response = await client.PostAsync(url, content);
// 判断请求是否成功
if (response.IsSuccessStatusCode)
{
var responseBody = await response.Content.ReadAsByteArrayAsync();
tcs.SetResult((true, responseBody));
}
else
{
Debug.LogError($"请求失败,错误码: {(int)response.StatusCode}");
tcs.SetResult((false, Encoding.UTF8.GetBytes(response.ReasonPhrase)));
}
}
catch (Exception ex)
{
tcs.SetResult((false, Encoding.UTF8.GetBytes(ex.Message)));
}
}
return await tcs.Task;
}
}
#endregion
2. 示例代码
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
public class Test : MonoBehaviour
{
private WebRequest monoWebRequest;
private AsyncWebRequest asyncWebRequest;
public RawImage rawImage;
private void Awake()
{
monoWebRequest = gameObject.AddComponent<WebRequest>();
asyncWebRequest = new AsyncWebRequest();
}
// Start is called before the first frame update
void Start()
{
//GetData();
PostData();
}
private void GetData()
{
monoWebRequest.Get(
"https://api.52starxi.cn/api/img-4k/img.php",
(isComplete, result) =>
{
if (isComplete)
{
// 请求格式为IMG 显示到 Image上
LoadImageFromBytes(result);
Debug.Log($"协程Get请求成功");
}
else
{
Debug.LogError("协程Get请求失败");
}
});
asyncWebRequest.Get(
"https://v.api.aa1.cn/api/yiyan/index.php",
(isComplete, result) =>
{
if (isComplete)
{
Debug.Log($"异步Get请求成功:{Encoding.UTF8.GetString(result)}");
}
else
{
Debug.LogError("异步Get请求失败");
}
});
}
private void PostData()
{
var postData = new
{
title="测试邮件",
nr="测试邮件内容",
reveuser="123456@qq.com"
};
string body = JsonUtility.ToJson(postData);
monoWebRequest.Post("http://api.paomotools.top/mail/email.php", body, null,
(isComplete, result) =>
{
if (isComplete)
{
Debug.Log($"协程Post请求成功:{Encoding.UTF8.GetString(result)}");
}
else
{
Debug.LogError("协程Post请求失败");
}
});
asyncWebRequest.Post(
"http://api.paomotools.top/mail/email.php",
body,
null,
(isComplete, result) =>
{
if (isComplete)
{
Debug.Log($"异步Post请求成功:{Encoding.UTF8.GetString(result)}");
}
else
{
Debug.LogError($"异步Post请求失败:{Encoding.UTF8.GetString(result)}");
}
});
}
private void LoadImageFromBytes(byte[] imageData)
{
StartCoroutine(LoadImageFromByteArray(imageData));
}
IEnumerator LoadImageFromByteArray(byte[] imageData)
{
// 创建一个新的Texture2D对象
Texture2D texture = new Texture2D(2, 2); // 创建一个2x2的空纹理
// 加载图片数据到Texture2D对象
if (texture.LoadImage(imageData))
{
// 如果图片加载成功,设置RawImage的Texture
rawImage.texture = texture;
}
else
{
Debug.LogError("Failed to load image from byte array.");
}
yield return null;
}
}
3. 运行结果

