关于图片上传服务器请求内容过大的问题(Unity)
出现的问题:
webgl端 一百多万传字节的文件到40G的服务器,会报错网络请求太大直接炸网页
分析问题:
因为图片视频这种占内存的资源,一般都是不存服务器,存在第三方 云上的,例如图片 服务器这边只是存一个图片网址,而不是一张图片几十万长度的字节,
解决方案:
以图片举例:
无实体文件(直接以Base64格式上传)
网络上传工具类代码:
/* js参考博客(https://www.cnblogs.com/fdw-bk/p/5807739.html) 如何上传base64编码图片到七牛云 接口说明: POST /putb64/<Fsize>/key/<EncodedKey>/mimeType/<EncodedMimeType>/crc32/<Crc32>/x:user-var/<EncodedUserVarVal> Host: upload.qiniu.com Authorization: UpToken <UpToken> Content-Type: application/octet-stream <Base64EncodedFileContent> <Fsize>: 文件大小,必选。 <EncodedKey>: 可选,如果没有指定则:如果 uptoken.SaveKey 存在则基于 SaveKey 生产 key,否则用 hash 值作 key。 <EncodedMimeType>: 文件的 MIME 类型。可选,默认是 application/octet-stream。 <Crc32>: 文件内容的 crc32 校验值。可选,不指定则不进行校验。 Host :上传域名up.qiniu.com 用于服务端上传,upload.qiniu.com 用于客户端的上传 返回包: 200 OK { hash: <ETag> } */ using System; using System.Collections; using UnityEngine; using UnityEngine.Networking; public class C_UnityWebRequest : MonoBehaviour { //contextType 对应 yunRequestHeader public string contextType = "Content-Type"; public string yunRequestHeader = "application/octet-stream"; //yunAuthorization 对应 yunToken //yunToken需要从后端服务器给的接口获取 public string yunAuthorization = "Authorization"; public string yunToken = "UpToken 5N--mUKCKuosGc7FvcaoR7tpN9WED91bqLa2la8w:HExIn5uTDXHyCaGdHc_EliwHrcY=:eyJwZXJzaXN0ZW50UGlwZWxpbmUiOiJ2aWRlb19jb252ZXJ0Iiwic2NvcGUiOiJoY2ltZyIsInJldHVybkJvZHkiOiJ7XCJrZXlcIjpcImh0dHA6Ly9oY2ltZy5wY2NlZHUuY24vJChrZXkpXCIsXCJoYXNoXCI6XCIkKGV0YWcpXCIsXCJidWNrZXRcIjpcIiQoYnVja2V0KVwiLFwiZnNpemVcIjokKGZzaXplKX0iLCJkZWFkbGluZSI6MTU5NDM1MTY5NX0="; //默认七牛云华东服务器 public string url = "http://upload.qiniup.com/putb64/";//+bytes.Length(需要跟上上传图片的字节大小) static C_UnityWebRequest _instance; public static C_UnityWebRequest Instance { get { if (_instance == null) { GameObject mounter = new GameObject("C_UnityWebRequest"); _instance = mounter.AddComponent<C_UnityWebRequest>(); } return _instance; } } /// <summary> /// 提交Post请求 /// </summary> /// <param name="url">请求地址</param> /// <param name="postData">上传到数据库的表单参数</param> /// <param name="actionResult">请求的回调</param> public void Post(string url, byte[] postData, Action<UnityWebRequest> actionResult) { StartCoroutine(PostUrl(url, postData, actionResult)); } IEnumerator PostUrl(string url, byte[] postData, Action<UnityWebRequest> actionResult) { using (UnityWebRequest uwr = new UnityWebRequest(url, "POST")) { uwr.uploadHandler = new UploadHandlerRaw(postData); uwr.downloadHandler = new DownloadHandlerBuffer(); uwr.SetRequestHeader(contextType, yunRequestHeader); uwr.SetRequestHeader(yunAuthorization, yunToken); yield return uwr.SendWebRequest(); actionResult?.Invoke(uwr); } } }
测试功能代码:
using System; using UnityEngine; using UnityEngine.Networking; public class UpLoadBase64 : MonoBehaviour { C_UnityWebRequest cc; void Awake() { cc = C_UnityWebRequest.Instance; } void Start() { //测试 Rect rc_3d = new Rect(Screen.width * 0f, Screen.height * 0f, Screen.width * 1f, Screen.height * 1f); Texture2D _3dTexture0 = CaptureCamera(Camera.main, rc_3d); byte[] bytesArr = _3dTexture0.EncodeToJPG(); string strbaser64 = Convert.ToBase64String(bytesArr); cc.Post(cc.url + bytesArr.Length, System.Text.Encoding.UTF8.GetBytes(strbaser64), (UnityWebRequest uwr) => GetMesage(uwr)); } /// <summary> /// 相机画面截图 /// </summary> /// <param name="camera"></param> /// <param name="rect"></param> /// <returns></returns> Texture2D CaptureCamera(Camera camera, Rect rect) { //创建一个RenderTexture对象 RenderTexture rt = new RenderTexture((int)rect.width, (int)rect.height, 0); camera.targetTexture = rt; camera.Render(); RenderTexture.active = rt; Texture2D screenShot = new Texture2D((int)rect.width, (int)rect.height, TextureFormat.RGB24, false); screenShot.ReadPixels(rect, 0, 0); screenShot.Apply(); camera.targetTexture = null; RenderTexture.active = null; Destroy(rt); return screenShot; } /// <summary> /// 图片转base64 /// </summary> /// <param name="t2d"></param> /// <returns></returns> public string Texture2DToBase64(Texture2D t2d) { byte[] bytesArr = t2d.EncodeToJPG(); string strbaser64 = Convert.ToBase64String(bytesArr); return strbaser64; } //打印返回请求,key为返回的图片网址,再传给后台服务器 void GetMesage(UnityWebRequest uwr) { Debug.Log("Code:" + uwr.responseCode + ",提示:" + uwr.downloadHandler.text); } }
测试成功截图:
有实体文件(请按照参考云开发文档按照对应文档格式上传)
https://developer.qiniu.com/kodo/sdk/1237/csharp