UnityWebRequest

作者:追风剑情 发布于:2019-12-12 16:43 分类:Unity3d

示例一:上传视频


  1. /// <summary>
  2. /// 上传视频
  3. /// </summary>
  4. /// <param name="url">上传视频地址</param>
  5. /// <param name="bytes">视频文件内容</param>
  6. /// <returns></returns>
  7. IEnumerator UpLoadVideo(string url, byte[] bytes)
  8. {
  9. yield return null;
  10. WWWForm form = new WWWForm();
  11. form.AddField("id", 123);
  12. form.AddBinaryData("file", bytes, "my_video.mp4", "video/mp4");
  13.  
  14. //byte[] bodyRaw = Encoding.UTF8.GetBytes(postDataString);//发送原始数据(即,数据不组织成表单)
  15. //UnityWebRequest request = new UnityWebRequest(url, "POST");
  16. UnityWebRequest request = UnityWebRequest.Post(url, form);
  17. request.timeout = 5;
  18. //https://docs.unity3d.com/ScriptReference/Networking.UnityWebRequest-useHttpContinue.html
  19. //true: 包含Expect: 100-Continue请求头, http会提前返回,这会导至后面的isNetworkError=true, responseCode=100
  20. //false: 确保http请求完毕后再返回
  21. request.useHttpContinue = false;
  22. request.chunkedTransfer = false; //false:不希望服务器分块返回数据
  23. request.SetRequestHeader("Content-Type", "application/json;charset=utf-8");
  24. //如果不指定post表单,需要这样上传原始数据
  25. //request.uploadHandler = (UploadHandler)new UploadHandlerRaw(bodyRaw);
  26. //request.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
  27. //加上yield return 直到请求完成程序才会继续往下执行
  28. //yield return request.SendWebRequest();
  29.  
  30. //调用后会立即返回,程序继续往下执行
  31. request.SendWebRequest();
  32.  
  33. while (!request.isDone)
  34. {
  35. Debug.Log("上传进度: " + request.uploadProgress);
  36. yield return new WaitForSeconds(0.1f);
  37. }
  38.  
  39. if (request.isHttpError || request.isNetworkError || request.responseCode != 200)
  40. {
  41. Debug.LogErrorFormat("上传视频出错\n{0}", request.error);
  42. yield break; //跳出协程
  43. }
  44.  
  45. Debug.Log("上传视频成功!");
  46. }
  47.  
  48. // Post原始数据(即,非表单)
  49. public IEnumerator PostRaw(string url, string data, Action completedCallback = null, Action errorCallback = null)
  50. {
  51. yield return null;
  52. byte[] postBytes = Encoding.UTF8.GetBytes(data);
  53. DownloadHandler downloadHandler = new DownloadHandlerBuffer();
  54. UploadHandler uploadHandler = new UploadHandlerRaw(postBytes);
  55. UnityWebRequest request = new UnityWebRequest(url, UnityWebRequest.kHttpVerbPOST);
  56. request.SetRequestHeader("Content-Type", "application/json;charset=utf-8");
  57. request.SetRequestHeader("Accept", "application/json");
  58. //设置Accept-Charset会报InvalidOperationException异常
  59. //InvalidOperationException: Cannot override system-specified headers
  60. //request.SetRequestHeader("Accept-Charset", "utf-8");
  61. //request.SetRequestHeader("Content-Length", postBytes.Length.ToString());
  62. request.timeout = 30; //单位:秒
  63. request.useHttpContinue = false;//false:直接上传post数据,不需要发送前征询服务器情况
  64. request.chunkedTransfer = false;//false:不希望服务器分块返回数据
  65. request.downloadHandler = downloadHandler;
  66. //如果不指定post表单,需要这样上传原始数据
  67. request.uploadHandler = uploadHandler;
  68. //yield return request.SendWebRequest(); //同步请求(请求完成后才会继续往下执行)
  69. request.SendWebRequest(); //异步请求
  70. while (!request.isDone)
  71. yield return new WaitForSeconds(0.1f);
  72. if (request.isHttpError || request.isNetworkError || request.responseCode != 200)
  73. {
  74. Debug.LogErrorFormat("Post Error\n{0}", request.error);
  75. if (errorCallback != null)
  76. errorCallback();
  77. yield break;//跳出协程
  78. }
  79. Debug.Log("Post完成!");
  80. Debug.LogFormat("result={0}", request.downloadHandler.text);
  81. string json = request.downloadHandler.text;
  82. if (completedCallback != null)
  83. completedCallback(json);
  84. }

示例二:上传器


  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using System.Net.Mime;
  6. using System.Text;
  7. using UnityEngine;
  8. using UnityEngine.Networking;
  9. /// <summary>
  10. /// 资源上传器 (multipart/form-data)
  11. /// </summary>
  12. public class AssetUpLoader : MonoBehaviour
  13. {
  14. public static AssetUpLoader Instance { get; private set; }
  15. public bool dontDestroyOnLoad = true;
  16. public bool isSingleInstance = true;
  17. //上传队列
  18. private Queue<AssetObject> m_UploadQueue = new Queue<AssetObject>();
  19. private bool m_UpLoading = false;
  20.  
  21. private void Awake()
  22. {
  23. if (dontDestroyOnLoad)
  24. DontDestroyOnLoad(gameObject);
  25.  
  26. if (isSingleInstance)
  27. Instance = this;
  28. }
  29.  
  30. private void Update()
  31. {
  32. if (m_UpLoading || m_UploadQueue.Count <= 0)
  33. return;
  34.  
  35. AssetObject asset = m_UploadQueue.Dequeue();
  36. StartCoroutine(CoroutineUpLoad(asset));
  37. }
  38.  
  39. public void UpLoad(AssetObject asset)
  40. {
  41. if (asset == null || string.IsNullOrEmpty(asset.url))
  42. return;
  43. m_UploadQueue.Enqueue(asset);
  44. }
  45.  
  46. // 上传本地资源
  47. public void UpLoadLocal(AssetObject asset)
  48. {
  49. StartCoroutine(UpLoadLocalCoroutine(asset));
  50. }
  51.  
  52. private IEnumerator UpLoadLocalCoroutine(AssetObject asset)
  53. {
  54. yield return null;
  55. Texture2D texture = null;
  56. using (WWW www = new WWW(asset.localPath))
  57. {
  58. while (!www.isDone)
  59. yield return null;
  60.  
  61. if (!string.IsNullOrEmpty(www.error)) {
  62. Debug.LogErrorFormat("load local asset error: {0}\n{1}", www.error, www.url);
  63. yield break;
  64. }
  65. texture = www.texture;
  66. }
  67. if (texture != null)
  68. {
  69. asset.bytes = texture.EncodeToJPG();
  70. m_UploadQueue.Enqueue(asset);
  71. }
  72. }
  73.  
  74. /// <summary>
  75. /// 上传资源
  76. /// </summary>
  77. /// <param name="url">上传地址</param>
  78. /// <param name="bytes">资源内容</param>
  79. /// <returns></returns>
  80. IEnumerator CoroutineUpLoad(AssetObject assetObject)
  81. {
  82. Debug.LogFormat("begin upload: {0}", assetObject.fileName);
  83. m_UpLoading = true;
  84. yield return null;
  85. DownloadHandler downloadHandler = new DownloadHandlerBuffer();
  86. UnityWebRequest request = assetObject.unityWebRequest;
  87. request.downloadHandler = downloadHandler;
  88. request.SendWebRequest();
  89.  
  90. while (!request.isDone)
  91. {
  92. Debug.Log("上传进度: " + request.uploadProgress);
  93. assetObject.uploadProgress = request.uploadProgress;
  94. if (assetObject.OnProgressCallback != null)
  95. assetObject.OnProgressCallback(assetObject);
  96. yield return new WaitForSeconds(0.1f);
  97. }
  98.  
  99. if (request.isHttpError || request.isNetworkError || request.responseCode != 200)
  100. {
  101. Debug.LogErrorFormat("上传资源出错\n{0}\n{1}", request.error, assetObject.url);
  102. if (assetObject.OnErrorCallback != null)
  103. assetObject.OnErrorCallback(assetObject);
  104. assetObject.Dispose();
  105. m_UpLoading = false;
  106. yield break;
  107. }
  108.  
  109. Debug.Log("上传资源完成!");
  110. Debug.LogFormat("{0}", request.downloadHandler.text);
  111. assetObject.result = request.downloadHandler.text;
  112. if (assetObject.OnCompletedCallback != null)
  113. assetObject.OnCompletedCallback(assetObject);
  114. assetObject.Dispose();
  115. m_UpLoading = false;
  116. }
  117.  
  118. /// <summary>
  119. /// 表单编码方式
  120. /// Multipart格式文档
  121. // https://www.cnblogs.com/greenerycn/archive/2010/05/15/csharp_http_post.html
  122. // https://www.w3.org/TR/html401/interact/forms.html#h-17.13.4
  123. /// </summary>
  124. public class FormEnctype
  125. {
  126. //对于发送大量二进制数据或包含非ASCII字符的文本效率不高
  127. public const string APPLICATION_X_WWW_FORM_URLENCODED = "application/x-www-form-urlencoded";
  128. //提交包含文件,非ASCII数据和二进制数据的表单
  129. public const string MULTIPART_FORM_DATA = "multipart/form-data";
  130. }
  131.  
  132. /// <summary>
  133. /// 资源对象
  134. /// </summary>
  135. public class AssetObject
  136. {
  137. public string headerContentType = FormEnctype.APPLICATION_X_WWW_FORM_URLENCODED;
  138. public string id = string.Empty; //用户ID
  139. public string url = string.Empty;
  140. public string localPath = string.Empty; //本地资源路径
  141. public byte[] bytes = null;
  142. //.jpg "image/jpeg"
  143. //.mp4 "video/mp4"
  144. public string mimeType = string.Empty;
  145. public string fileName = string.Empty;
  146. public float uploadProgress = 0.0f;
  147. public string result = string.Empty; //服务器返回数据
  148.  
  149. public Action<AssetObject> OnCompletedCallback;
  150. public Action<AssetObject> OnProgressCallback;
  151. public Action<AssetObject> OnErrorCallback;
  152.  
  153. public string MimeType
  154. {
  155. get
  156. {
  157. if (string.IsNullOrWhiteSpace(mimeType) && !string.IsNullOrWhiteSpace(fileName))
  158. {
  159. if (fileName.EndsWith(".jpg"))
  160. mimeType = "image/jpeg";
  161. else if (fileName.EndsWith(".png"))
  162. mimeType = "image/png";
  163. else if (fileName.EndsWith(".mp4"))
  164. mimeType = "video/mp4";
  165. }
  166. return mimeType;
  167. }
  168. }
  169.  
  170. public WWWForm wwwForm
  171. {
  172. get
  173. {
  174. WWWForm form = new WWWForm();
  175. form.AddField("id", id);
  176. form.AddBinaryData("file", bytes, fileName, MimeType);
  177.  
  178. return form;
  179. }
  180. }
  181.  
  182. public UnityWebRequest unityWebRequest
  183. {
  184. get
  185. {
  186. UnityWebRequest request = null;
  187. switch (headerContentType)
  188. {
  189. case FormEnctype.APPLICATION_X_WWW_FORM_URLENCODED:
  190. request = UnityWebRequest.Post(url, wwwForm);
  191. request.SetRequestHeader("Content-Type", "application/json;charset=utf-8");
  192. break;
  193. case FormEnctype.MULTIPART_FORM_DATA:
  194. //分界线
  195. byte[] boundary = UnityWebRequest.GenerateBoundary();
  196. //结束分界线
  197. byte[] terminate = Encoding.UTF8.GetBytes(String.Concat("\r\n--", Encoding.UTF8.GetString(boundary), "--"));
  198.  
  199. //Content-Type
  200. string contentType = String.Concat("multipart/form-data; boundary=", Encoding.UTF8.GetString(boundary));
  201.  
  202. //表单
  203. List<IMultipartFormSection> form = new List<IMultipartFormSection>();
  204. form.Add(new MultipartFormFileSection("file", bytes, Path.GetFileName(fileName), MimeType));
  205.  
  206. //序列化表单
  207. byte[] formSections = UnityWebRequest.SerializeFormSections(form, boundary);
  208.  
  209. byte[] body = new byte[formSections.Length + terminate.Length];
  210. Buffer.BlockCopy(formSections, 0, body, 0, formSections.Length);
  211. Buffer.BlockCopy(terminate, 0, body, formSections.Length, terminate.Length);
  212.  
  213. request = new UnityWebRequest(url, UnityWebRequest.kHttpVerbPOST);
  214. request.uploadHandler = (UploadHandler)new UploadHandlerRaw(body);
  215. request.uploadHandler.contentType = contentType;
  216. break;
  217. }
  218.  
  219. request.timeout = 30;
  220. request.useHttpContinue = false;
  221. request.chunkedTransfer = false;
  222.  
  223. return request;
  224. }
  225. }
  226.  
  227. public void Dispose()
  228. {
  229. bytes = null;
  230. OnCompletedCallback = null;
  231. OnProgressCallback = null;
  232. OnErrorCallback = null;
  233. }
  234. }
  235. }

Http请求


  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using System.Text;
  6. using UnityEngine;
  7. using UnityEngine.Networking;
  8. /// <summary>
  9. /// 与Web端交互
  10. /// </summary>
  11. public class HttpWebRequest : MonoBehaviour
  12. {
  13. public static HttpWebRequest Instance { get; private set; }
  14. private void Awake()
  15. {
  16. DontDestroyOnLoad(gameObject);
  17. Instance = this;
  18. }
  19.  
  20. // Delete请求
  21. public void Delete(string url, Action<string> completedCallback = null, Action<string> errorCallback = null)
  22. {
  23. StartCoroutine(DeleteRequest(url, completedCallback, errorCallback));
  24. }
  25.  
  26. public IEnumerator DeleteRequest(string url, Action<string> completedCallback = null, Action<string> errorCallback = null)
  27. {
  28. yield return null;
  29. Debug.LogFormat("DELETE: {0}", url);
  30. UnityWebRequest request = DeleteUnityWebRequest(url);
  31. //yield return request.SendWebRequest(); //同步请求(请求完成后才会继续往下执行)
  32. request.SendWebRequest(); //异步请求
  33.  
  34. while (!request.isDone)
  35. yield return new WaitForSeconds(0.1f);
  36. if (request.isHttpError || request.isNetworkError || request.responseCode != 200)
  37. {
  38. Debug.LogErrorFormat("DELETE Error\n{0}", request.error);
  39. if (errorCallback != null)
  40. errorCallback(request.error);
  41. yield break;//跳出协程
  42. }
  43. Debug.Log("DELETE 请求返回!");
  44. Debug.LogFormat("result={0}", request.downloadHandler.text);
  45. string json = request.downloadHandler.text;
  46. if (completedCallback != null)
  47. completedCallback(json);
  48. }
  49. // Get请求
  50. public void Get(string url, Action<string> completedCallback = null, Action<string> errorCallback = null)
  51. {
  52. StartCoroutine(GetRequest(url, completedCallback, errorCallback));
  53. }
  54.  
  55. public IEnumerator GetRequest(string url, Action<string> completedCallback = null, Action<string> errorCallback = null)
  56. {
  57. yield return null;
  58. Debug.LogFormat("GET: {0}", url);
  59. UnityWebRequest request = GetUnityWebRequest(url);
  60. //yield return request.SendWebRequest(); //同步请求(请求完成后才会继续往下执行)
  61. request.SendWebRequest(); //异步请求
  62.  
  63. while (!request.isDone)
  64. yield return new WaitForSeconds(0.1f);
  65. if (request.isHttpError || request.isNetworkError || request.responseCode != 200)
  66. {
  67. Debug.LogErrorFormat("GET Error\n{0}", request.error);
  68. if (errorCallback != null)
  69. errorCallback(request.error);
  70. yield break;//跳出协程
  71. }
  72. Debug.Log("GET 请求返回!");
  73. Debug.LogFormat("result={0}", request.downloadHandler.text);
  74. string json = request.downloadHandler.text;
  75. if (completedCallback != null)
  76. completedCallback(json);
  77. }
  78.  
  79. // Post原始数据(即,非表单)
  80. public void Post(string url, string data, Action<string> completedCallback = null, Action<string> errorCallback = null)
  81. {
  82. StartCoroutine(PostRaw(url, data, completedCallback, errorCallback));
  83. }
  84.  
  85. // Post原始数据(即,非表单)
  86. public IEnumerator PostRaw(string url, string data, Action<string> completedCallback = null, Action<string> errorCallback = null)
  87. {
  88. yield return null;
  89. Debug.LogFormat("POST: {0}\n{1}", url, data);
  90. byte[] postBytes = Encoding.UTF8.GetBytes(data);
  91. UnityWebRequest request = PostUnityWebRequest(url, data);
  92. //yield return request.SendWebRequest(); //同步请求(请求完成后才会继续往下执行)
  93. request.SendWebRequest(); //异步请求
  94.  
  95. while (!request.isDone)
  96. yield return new WaitForSeconds(0.1f);
  97. if (request.isHttpError || request.isNetworkError || request.responseCode != 200)
  98. {
  99. Debug.LogErrorFormat("POST Error\n{0}", request.error);
  100. if (errorCallback != null)
  101. errorCallback(request.error);
  102. yield break;//跳出协程
  103. }
  104. Debug.Log("POST 请求返回!");
  105. Debug.LogFormat("result={0}", request.downloadHandler.text);
  106. string json = request.downloadHandler.text;
  107. if (completedCallback != null)
  108. completedCallback(json);
  109. }
  110.  
  111. // GET UnityWebRequest
  112. public UnityWebRequest GetUnityWebRequest(string url)
  113. {
  114. DownloadHandler downloadHandler = new DownloadHandlerBuffer();
  115. UnityWebRequest request = new UnityWebRequest(url, UnityWebRequest.kHttpVerbGET);
  116. request.SetRequestHeader("Content-Type", "application/json");
  117. request.SetRequestHeader("Accept", "application/json");
  118. request.timeout = 10;
  119. request.useHttpContinue = false;
  120. request.chunkedTransfer = false;
  121. request.downloadHandler = downloadHandler;
  122. return request;
  123. }
  124.  
  125. // POST UnityWebRequest
  126. public UnityWebRequest PostUnityWebRequest(string url, string postData)
  127. {
  128. byte[] postBytes = Encoding.UTF8.GetBytes(postData);
  129. DownloadHandler downloadHandler = new DownloadHandlerBuffer();
  130. UnityWebRequest request = new UnityWebRequest(url, UnityWebRequest.kHttpVerbPOST);
  131. request.SetRequestHeader("Content-Type", "application/json");
  132. request.SetRequestHeader("Accept", "application/json");
  133. request.timeout = 10;
  134. request.useHttpContinue = false;
  135. request.chunkedTransfer = false;
  136. request.downloadHandler = downloadHandler;
  137. request.uploadHandler = (UploadHandler)new UploadHandlerRaw(postBytes);
  138. return request;
  139. }
  140.  
  141. // DELETE UnityWebRequest
  142. public UnityWebRequest DeleteUnityWebRequest(string url)
  143. {
  144. DownloadHandler downloadHandler = new DownloadHandlerBuffer();
  145. UnityWebRequest request = new UnityWebRequest(url, UnityWebRequest.kHttpVerbDELETE);
  146. request.SetRequestHeader("Content-Type", "application/json");
  147. request.SetRequestHeader("Accept", "application/json");
  148. request.timeout = 10;
  149. request.useHttpContinue = false;
  150. request.chunkedTransfer = false;
  151. request.downloadHandler = downloadHandler;
  152. return request;
  153. }
  154. }


关于 CertificateHandler

UnityWebRequest request = new UnityWebRequest();
// Https 需要设置证书验证
request.certificateHandler = new AcceptAllCertificatesSignedWithASpecificKeyPublicKey();

  1. using UnityEngine;
  2. using UnityEngine.Networking;
  3. using System.Security.Cryptography.X509Certificates;
  4.  
  5. /// <summary>
  6. /// https://docs.unity3d.com/ScriptReference/Networking.CertificateHandler.ValidateCertificate.html
  7. /// https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning#.Net
  8. /// </summary>
  9. public class AcceptAllCertificatesSignedWithASpecificKeyPublicKey : CertificateHandler
  10. {
  11. // Encoded RSAPublicKey
  12. private static string PUB_KEY = "3082010A0282010100C3D57BDD8594A0E4948CF35B24B2A5CC3D7455E8DADAF9C410EE6CCD7DDD0CEB4A9A62D4E065AED004E0467107A93CAF69A7CAB61A57A306171213F39C3E601D621B144D8C97674A9753177713C3A9571D1821D8EAAF821E21F94F88658E2CB68EC7994B5130CD24C89813BDD19F7DDA331900D5C70310F65FC5624BC65EF6327F1EF74896B18A59FD34F095762F9B376D5F74D187ECA86D807CACF37A597E89B2A0E690C4146971FBEA641E61AFA28C0F58A453092DEA570BA405C720A77621711BCE1A902CEC13BCC34FAEFBD67E7C671F3A85883D2F6D583843F000B1FCCAA068C09FA5DEF69F800002D332A60549C7216B3FF929B2B562EF0E3E97B776E90203010001";
  13.  
  14. //负责拒绝或接受在 https 请求上接收到的证书
  15. //注意:自定义证书验证目前仅针对以下平台实施 - Android、iOS、tvOS 和桌面平台
  16. //如果不需要验证,可以让这个方法直接返回true
  17. protected override bool ValidateCertificate(byte[] certificateData)
  18. {
  19. X509Certificate2 certificate = new X509Certificate2(certificateData);
  20. string pk = certificate.GetPublicKeyString();
  21. if (pk.Equals(PUB_KEY))
  22. return true;
  23.  
  24. // Bad dog
  25. return false;
  26. }
  27. }

示例:Post发送表单

private IEnumerator PostFormCoroutine(string url, WWWForm form)
	UnityWebRequest request = UnityWebRequest.Post(url, form);
	request.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded");
	request.timeout = 5;
	yield return request.SendWebRequest();
	if (request.result == UnityWebRequest.Result.ProtocolError || 
		request.result == UnityWebRequest.Result.ConnectionError ||
		request.result == UnityWebRequest.Result.DataProcessingError ||
		request.responseCode != 200)
	{
		Debug.LogErrorFormat("Http请求出错({0})\n{1}", request.responseCode, request.error);
		yield break; //跳出协程
	}
	string text = request.downloadHandler.text;
	Debug.Log(text); 
}  

示例:Post发送json

private IEnumerator PostJsonCoroutine(string url, string json, string token)
	UnityWebRequest request = new UnityWebRequest(url, UnityWebRequest.kHttpVerbPOST);
	byte[] data = Encoding.UTF8.GetBytes(json);
	request.uploadHandler = (UploadHandler)new UploadHandlerRaw(data);
	request.downloadHandler = new DownloadHandlerBuffer();
	request.SetRequestHeader("Content-Type", "application/json;charset=utf-8");
	//认证信息根据项目实际情况传参,这里仅作示范
	request.SetRequestHeader("Authorization", token);
	request.timeout = 5;
	yield return request.SendWebRequest();
	if (request.result == UnityWebRequest.Result.ProtocolError ||
		request.result == UnityWebRequest.Result.ConnectionError ||
		request.result == UnityWebRequest.Result.DataProcessingError ||
		request.responseCode != 200)
	{
		Debug.LogErrorFormat("Http请求出错({0})\n{1}", request.responseCode, request.error);
		yield break; //跳出协程
	}
	string text = request.downloadHandler.text;
	Debug.Log(text);
}  

注意,UnityWebRequest.Post()方法有bug,会使传到后台的json数据多个无效字符,导致json解析报错。


  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using System.Text;
  6. using Unity.VisualScripting;
  7. using UnityEngine;
  8. using UnityEngine.Networking;
  9. /// <summary>
  10. /// Web请求辅助类
  11. /// Unity 2022+ 默认不支持Http请求,需要在 Project Settings 中开启
  12. /// [Project Settings -> Player -> Allow downloads over HTTP* 设置为 Always allowed]
  13. /// </summary>
  14. public sealed class WebRequestHelper
  15. {
  16. // 设置请求头
  17. private static void SetRequestHeader(UnityWebRequest request, Dictionary<string, string> header = null)
  18. {
  19. if (request == null)
  20. return;
  21.  
  22. request.SetRequestHeader("Content-Type", "application/json;charset=utf-8");
  23. request.SetRequestHeader("Accept", "application/json");
  24. request.SetRequestHeader("Authorization", "");
  25.  
  26. if (header == null)
  27. return;
  28.  
  29. foreach (string key in header.Keys)
  30. {
  31. string value = header[key];
  32. if (value == null)
  33. continue;
  34. request.SetRequestHeader(key, value);
  35. }
  36. }
  37.  
  38. // 解析
  39. private static void ParseAsync(UnityWebRequestAsyncOperation async, Action<string> completedCallback = null, Action<string> errorCallback = null)
  40. {
  41. string error = async.webRequest.error;
  42. if (!string.IsNullOrEmpty(error))
  43. {
  44. async.webRequest.Dispose();
  45. if (errorCallback == null)
  46. Debug.LogErrorFormat("请求出错: {0}", error);
  47. errorCallback?.Invoke(error);
  48. }
  49. else
  50. {
  51. string text = async.webRequest.downloadHandler.text;
  52. async.webRequest.Dispose();
  53. completedCallback?.Invoke(text);
  54. }
  55. }
  56.  
  57. // 采用GET,向后端请求数据
  58. public static UnityWebRequestAsyncOperation Get(string url, Dictionary<string, string> header = null)
  59. {
  60. DownloadHandler downloadHandler = new DownloadHandlerBuffer();
  61. UnityWebRequest request = new UnityWebRequest(url, UnityWebRequest.kHttpVerbGET);
  62. request.downloadHandler = downloadHandler;
  63. SetRequestHeader(request, header);
  64. request.timeout = 5;
  65. request.chunkedTransfer = false;
  66. UnityWebRequestAsyncOperation async = request.SendWebRequest();
  67. return async;
  68. }
  69.  
  70. public static IEnumerator GetAsync(string url, Dictionary<string, string> header = null, Action<string> completedCallback = null, Action<string> errorCallback = null, Action<float> progressCallback = null)
  71. {
  72. yield return null;
  73. UnityWebRequestAsyncOperation async = Get(url, header);
  74. while (!async.isDone)
  75. {
  76. progressCallback?.Invoke(async.progress);
  77. yield return new WaitForNextFrameUnit();
  78. }
  79. ParseAsync(async, completedCallback, errorCallback);
  80. }
  81.  
  82. // 采用POST,向后端发送原始数据
  83. public static UnityWebRequestAsyncOperation Post(string url, byte[] rawData, Dictionary<string, string> header = null)
  84. {
  85. DownloadHandler downloadHandler = new DownloadHandlerBuffer();
  86. UploadHandler uploadHandler = new UploadHandlerRaw(rawData);
  87. UnityWebRequest request = new UnityWebRequest(url, UnityWebRequest.kHttpVerbPOST);
  88. request.downloadHandler = downloadHandler;
  89. request.uploadHandler = uploadHandler;
  90. SetRequestHeader(request, header);
  91. request.timeout = 5;
  92. UnityWebRequestAsyncOperation async = request.SendWebRequest();
  93. return async;
  94. }
  95.  
  96. public static UnityWebRequestAsyncOperation Post(string url, string rawData, Dictionary<string, string> header = null)
  97. {
  98. byte[] postBytes = Encoding.UTF8.GetBytes(rawData);
  99. return Post(url, postBytes, header);
  100. }
  101.  
  102. public static IEnumerator PostAsync(string url, string rawData, Dictionary<string, string> header, Action<string> completedCallback = null, Action<string> errorCallback = null, Action<float> progressCallback = null)
  103. {
  104. yield return null;
  105. UnityWebRequestAsyncOperation async = Post(url, rawData, header);
  106. while (!async.isDone)
  107. {
  108. progressCallback?.Invoke(async.progress);
  109. yield return new WaitForNextFrameUnit();
  110. }
  111. ParseAsync(async, completedCallback, errorCallback);
  112. }
  113.  
  114. // 表单请求 POST
  115. public static IEnumerator PostFormAsync(string url, WWWForm form, Dictionary<string, string> header, Action<string> completedCallback = null, Action<string> errorCallback = null, Action<float> progressCallback = null)
  116. {
  117. yield return null;
  118. UnityWebRequest request = UnityWebRequest.Post(url, form);
  119. SetRequestHeader(request, header);
  120. UnityWebRequestAsyncOperation async = request.SendWebRequest();
  121. while (!async.isDone)
  122. {
  123. progressCallback?.Invoke(async.progress);
  124. yield return new WaitForNextFrameUnit();
  125. }
  126. ParseAsync(async, completedCallback, errorCallback);
  127. }
  128.  
  129. //默认请求头
  130. public static Dictionary<string, string> GetDefaultRequestHeader()
  131. {
  132. Dictionary<string, string> header = new Dictionary<string, string>();
  133. header.Add("Content-Type", "application/json;charset=UTF-8");
  134. header.Add("Access-Control-Allow-0rigin", "*");
  135. header.Add("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE, PATCH");
  136. header.Add("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  137. return header;
  138. }
  139.  
  140. // 异步加载文本
  141. public static IEnumerator LoadTextAsync(string url, Action<string> completedCallback = null, Action<string> errorCallback = null, Action<float> progressCallback = null)
  142. {
  143. using (UnityWebRequest webRequest = UnityWebRequest.Get(url))
  144. {
  145. webRequest.SendWebRequest();
  146. while (!webRequest.isDone)
  147. {
  148. progressCallback?.Invoke(webRequest.downloadProgress);
  149. yield return null;
  150. }
  151. if (webRequest.result == UnityWebRequest.Result.ConnectionError /*webRequest.isNetworkError*/
  152. || webRequest.result == UnityWebRequest.Result.ProtocolError/*webRequest.isHttpError*/)
  153. {
  154. Debug.LogErrorFormat("{0}\n{1}", webRequest.error.ToString(), url);
  155. errorCallback?.Invoke(webRequest.error);
  156. }
  157. else
  158. {
  159. var text = webRequest.downloadHandler.text;
  160. completedCallback?.Invoke(text);
  161. }
  162. }
  163. }
  164.  
  165. // 异步加载图片
  166. public static IEnumerator LoadTextureAsync(string url, Action<Texture2D> completedCallback = null, Action<string> errorCallback = null, Action<float> progressCallback = null)
  167. {
  168. using (UnityWebRequest webRequest = UnityWebRequestTexture.GetTexture(url))
  169. {
  170. webRequest.SendWebRequest();
  171. while (!webRequest.isDone)
  172. {
  173. progressCallback?.Invoke(webRequest.downloadProgress);
  174. yield return null;
  175. }
  176. if (webRequest.result == UnityWebRequest.Result.ConnectionError /*webRequest.isNetworkError*/
  177. || webRequest.result == UnityWebRequest.Result.ProtocolError/*webRequest.isHttpError*/)
  178. {
  179. Debug.LogErrorFormat("{0}\n{1}", webRequest.error.ToString(), url);
  180. errorCallback?.Invoke(webRequest.error);
  181. }
  182. else
  183. {
  184. var texture = DownloadHandlerTexture.GetContent(webRequest);
  185. completedCallback?.Invoke(texture);
  186. }
  187. }
  188. }
  189.  
  190. // 异步加载 AudioClip
  191. public static IEnumerator LoadAudioAsync(string url, Action<AudioClip> completedCallback = null, Action<string> errorCallback = null, Action<float> progressCallback = null)
  192. {
  193. string ext = Path.GetExtension(url).ToLower();
  194. AudioType audioType = AudioType.WAV;
  195. switch (ext)
  196. {
  197. case ".wav":
  198. audioType = AudioType.WAV;
  199. break;
  200. case ".mp3":
  201. audioType = AudioType.MPEG;
  202. break;
  203. }
  204.  
  205. using (UnityWebRequest webRequest = UnityWebRequestMultimedia.GetAudioClip(url, audioType))
  206. {
  207. ((DownloadHandlerAudioClip)webRequest.downloadHandler).streamAudio = true;
  208. webRequest.SendWebRequest();
  209. while (!webRequest.isDone)
  210. {
  211. progressCallback?.Invoke(webRequest.downloadProgress);
  212. yield return null;
  213. }
  214. if (webRequest.result == UnityWebRequest.Result.ConnectionError /*webRequest.isNetworkError*/
  215. || webRequest.result == UnityWebRequest.Result.ProtocolError/*webRequest.isHttpError*/)
  216. {
  217. Debug.LogErrorFormat("{0}\n{1}", webRequest.error.ToString(), url);
  218. errorCallback?.Invoke(webRequest.error);
  219. }
  220. else
  221. {
  222. var audioClip = DownloadHandlerAudioClip.GetContent(webRequest);
  223. completedCallback?.Invoke(audioClip);
  224. }
  225. }
  226. }
  227.  
  228. // 异步加载 AssetBundle
  229. public static IEnumerator LoadAssetBundleAsync(string url, Action<AssetBundle> completedCallback = null, Action<string> errorCallback = null, Action<float> progressCallback = null)
  230. {
  231. using (UnityWebRequest webRequest = UnityWebRequestAssetBundle.GetAssetBundle(url))
  232. {
  233. ((DownloadHandlerAssetBundle)webRequest.downloadHandler).autoLoadAssetBundle = false;
  234. webRequest.SendWebRequest();
  235. while (!webRequest.isDone)
  236. {
  237. progressCallback?.Invoke(webRequest.downloadProgress);
  238. yield return null;
  239. }
  240. if (webRequest.result == UnityWebRequest.Result.ConnectionError /*webRequest.isNetworkError*/
  241. || webRequest.result == UnityWebRequest.Result.ProtocolError/*webRequest.isHttpError*/)
  242. {
  243. Debug.LogErrorFormat("{0}\n{1}", webRequest.error.ToString(), url);
  244. errorCallback?.Invoke(webRequest.error);
  245. }
  246. else
  247. {
  248. var assetBundle = DownloadHandlerAssetBundle.GetContent(webRequest);
  249. completedCallback?.Invoke(assetBundle);
  250. assetBundle.Unload(false);
  251. }
  252. }
  253. }
  254.  
  255. // 异步加载场景 AssetBundle
  256. public static IEnumerator LoadSceneAssetBundleAsync(string url, Action<AssetBundle> completedCallback = null, Action<string> errorCallback = null, Action<float> progressCallback = null, bool autoLoadScene = true, LoadSceneMode mode = LoadSceneMode.Single)
  257. {
  258. using (UnityWebRequest webRequest = UnityWebRequestAssetBundle.GetAssetBundle(url))
  259. {
  260. ((DownloadHandlerAssetBundle)webRequest.downloadHandler).autoLoadAssetBundle = false;
  261. webRequest.SendWebRequest();
  262. while (!webRequest.isDone)
  263. {
  264. progressCallback?.Invoke(webRequest.downloadProgress);
  265. yield return null;
  266. }
  267. if (webRequest.result == UnityWebRequest.Result.ConnectionError /*webRequest.isNetworkError*/
  268. || webRequest.result == UnityWebRequest.Result.ProtocolError/*webRequest.isHttpError*/)
  269. {
  270. Debug.LogErrorFormat("{0}\n{1}", webRequest.error.ToString(), url);
  271. errorCallback?.Invoke(webRequest.error);
  272. }
  273. else
  274. {
  275. //向外部逻辑返回进度100%
  276. progressCallback?.Invoke(webRequest.downloadProgress);
  277. var assetBundle = DownloadHandlerAssetBundle.GetContent(webRequest);
  278. completedCallback?.Invoke(assetBundle);
  279. if (autoLoadScene)
  280. {
  281. string sceneName = Path.GetFileNameWithoutExtension(url);
  282. SceneManager.LoadScene(sceneName, mode);
  283. }
  284.  
  285. //释放场景镜像资源。
  286. //注意:必须等场景成功激活后再调用Unload,否则会出现材质和shader丢失。
  287. //assetBundle.Unload(false);
  288. }
  289. }
  290. }
  291.  
  292. // 上传图片
  293. public static IEnumerator UploadTexture(string url, string filename, Dictionary<string, string> formField, Texture2D tex, Action<string> completedCallback = null, Action<string> errorCallback = null, Action<float> progressCallback = null)
  294. {
  295. yield return null;
  296.  
  297. if (tex == null)
  298. {
  299. Debug.LogError("上传的 Texture=null");
  300. yield break;
  301. }
  302.  
  303. if (string.IsNullOrEmpty(filename))
  304. {
  305. Debug.LogError("上传的 filename=null");
  306. yield break;
  307. }
  308.  
  309. //如果在非主线程调用EncodeToJPG()会报以下错。
  310. //UnityException: EncodeToJPG can only be called from the main thread.
  311. byte[] bytes = tex.EncodeToJPG();
  312. WWWForm form = new WWWForm();
  313. form.headers["Content-Type"] = "image/jpeg";
  314. form.AddBinaryData("file", bytes, $"{filename}");
  315. //添加更多字段参数
  316. if (formField != null)
  317. {
  318. foreach (var key in formField.Keys)
  319. {
  320. string value = formField[key];
  321. if (!string.IsNullOrEmpty(value))
  322. form.AddField(key, formField[key]);
  323. }
  324. }
  325.  
  326. UnityWebRequest request = UnityWebRequest.Post(url, form);
  327. UnityWebRequestAsyncOperation async = request.SendWebRequest();
  328. while (!async.isDone)
  329. {
  330. progressCallback?.Invoke(async.progress);
  331. yield return new WaitForNextFrameUnit();
  332. }
  333. ParseAsync(async, completedCallback, errorCallback);
  334. }
  335. }

标签: Unity3d

Powered by emlog  蜀ICP备18021003号-1   sitemap

川公网安备 51019002001593号