关于图片上传服务器请求内容过大的问题(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

posted @ 2020-07-10 10:37  方是源  阅读(801)  评论(0编辑  收藏  举报
回顶部