Webgl缓存问题Failed to load ‘xxx/Build/public.data‘ Could not connect to cache: Cache API is not support

打包webgl后,发现每次加载资源特别慢,查看了浏览器的DevTools,发现有一条日志:

[UnityCache] Failed to load 'http://192.168.0.191:3000/Build/public.data' from indexedDB cache due to the error: Error: Could not connect to cache: Cache API is not supported.

查了官方文档:

Cache behavior in WebGL - Unity 手册

Data Caching

To access Data Caching, open the Publishing Setings for Web from File > Build Settings > Player Settings. This enables the browser to cache the main data files into the IndexedDB database.

Using the default browser HTTP cache doesn’t guarantee that the browser caches a particular response. This is because the browser HTTP cache has limited space, and the browser might not be able to cache files that are too large.

To improve your loading speed, IndexedDB allows you to cache files above the browser limit. When you cache more files, you increase the chance that downloaded content is available on the user’s machine during the next run of the build.

Data Caching only caches the .data files in the IndexedDB cache for HTTP responses. To cache AssetBundles, you need to enable Data Caching and override unityInstance.Module.cacheControl(). To do this, make sure Module.cacheControl(url) returns must-revalidate for the requested AssetBundle URL. For example, you can override the unityInstance.Module.cacheControl() function in the fulfillment callback of the Promise that createUnityInstance() returns. For further information on createUnityInstance(), see Compressed builds and server configuration.

发现是要在模板的index.html里的config配置中增加cacheControl的配置,加上就好了。

如下图

模板长这样:

<!DOCTYPE html>
<html lang="en-us">

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">

  <title>{{{ PRODUCT_NAME }}}</title>
    <link rel="shortcut icon" href="TemplateData/favicon.ico">
    <link rel="stylesheet" href="TemplateData/style.css">

</head>

<body>
   <div id="unity-container" class="unity-desktop">
      <canvas id="unity-canvas" width=960 height=600></canvas>
      <div id="unity-loading-bar">
        <div id="unity-logo"></div>
        <div id="unity-progress-bar-empty">
          <div id="unity-progress-bar-full"></div>
        </div>
      </div>
      <div id="unity-warning"> </div>
     
    </div>
		
  <script>
	  var container = document.querySelector("#unity-container");
      var canvas = document.querySelector("#unity-canvas");
      var loadingBar = document.querySelector("#unity-loading-bar");
      var progressBarFull = document.querySelector("#unity-progress-bar-full");
      var fullscreenButton = document.querySelector("#unity-fullscreen-button");
      var warningBanner = document.querySelector("#unity-warning");

      // Shows a temporary message banner/ribbon for a few seconds, or
      // a permanent error message on top of the canvas if type=='error'.
      // If type=='warning', a yellow highlight color is used.
      // Modify or remove this function to customize the visually presented
      // way that non-critical warnings and error messages are presented to the
      // user.
      function unityShowBanner(msg, type) {
        function updateBannerVisibility() {
          warningBanner.style.display = warningBanner.children.length ? 'block' : 'none';
        }
        var div = document.createElement('div');
        div.innerHTML = msg;
        warningBanner.appendChild(div);
        if (type == 'error') div.style = 'background: red; padding: 10px;';
        else {
          if (type == 'warning') div.style = 'background: yellow; padding: 10px;';
          setTimeout(function() {
            warningBanner.removeChild(div);
            updateBannerVisibility();
          }, 5000);
        }
        updateBannerVisibility();
      }

     var buildUrl = "Build";
    var loaderUrl = buildUrl + "/{{{ LOADER_FILENAME }}}";
       var config = {
           dataUrl: buildUrl + "/{{{ DATA_FILENAME }}}",
           frameworkUrl: buildUrl + "/{{{ FRAMEWORK_FILENAME }}}",
           codeUrl: buildUrl + "/{{{ CODE_FILENAME }}}",
           #if MEMORY_FILENAME
           memoryUrl: buildUrl + "/{{{ MEMORY_FILENAME }}}",
           #endif
           #if SYMBOLS_FILENAME
           symbolsUrl: buildUrl + "/{{{ SYMBOLS_FILENAME }}}",
           #endif
           streamingAssetsUrl: "StreamingAssets",
           companyName: "{{{ COMPANY_NAME }}}",
           productName: "{{{ PRODUCT_NAME }}}",
           productVersion: "{{{ PRODUCT_VERSION }}}",
	       showBanner: unityShowBanner,
	#if USE_DATA_CACHING
	   cacheControl: function (url) {
		 // Caching enabled for .data and .bundle files.
		 // Revalidate if file is up to date before loading from cache
		 if (url.match(/\.data/) || url.match(/\.bundle/)) {
			 return "must-revalidate";
		 }

		 // Caching enabled for .mp4 and .custom files
		 // Load file from cache without revalidation.
		 if (url.match(/\.mp4/) || url.match(/\.custom/)) {
			 return "immutable";
		 }
	 
		 // Disable explicit caching for all other files.
		 // Note: the default browser cache may cache them anyway.
		 return "no-store";
	   },
	#endif
    };

      // By default Unity keeps WebGL canvas render target size matched with
      // the DOM size of the canvas element (scaled by window.devicePixelRatio)
      // Set this to false if you want to decouple this synchronization from
      // happening inside the engine, and you would instead like to size up
      // the canvas DOM size and WebGL render target sizes yourself.
      // config.matchWebGLToCanvasSize = false;
	    if (/iPhone|iPad|iPod|Android/i.test(navigator.userAgent)) {
        container.className = "unity-mobile";
        // Avoid draining fillrate performance on mobile devices,
        // and default/override low DPI mode on mobile browsers.
        config.devicePixelRatio = 1;
        unityShowBanner('WebGL builds are not supported on mobile devices.');
      } else {
         canvas.style.width = "100vw";
        canvas.style.height = "100vh";
      }
      loadingBar.style.display = "block";

      var script = document.createElement("script");
      script.src = loaderUrl;
      script.onload = () => {
        createUnityInstance(canvas, config, (progress) => {
          progressBarFull.style.width = 100 * progress + "%";
        }).then((unityInstance) => {
          loadingBar.style.display = "none";
		   window.unityInstance = unityInstance; // <-- this
          fullscreenButton.onclick = () => {
            unityInstance.SetFullscreen(1);
          };
        }).catch((message) => {
        //  alert(message);
        });
      };
      document.body.appendChild(script);
	
	


  </script>
</body>

</html>

问题:

加上之后还是提示不支持,GoogleChrome浏览器测试的,后来在同事的浏览器测试没问题了

正常的情况是这样

<think>我们正在解决用户的问题:在加载Unity网页内容时,出现错误"Failed todownload fileBuild/unityBuild.data.br",原因是使用了file://协议而没有使用Web服务器。用户希望知道如何解决。根据错误信息,关键点在于:使用file://协议加载UnityWebGL内容时,由于浏览器的安全限制,不允许通过file://协议加载某些类型的资源(尤其是压缩的二进制文件)。因此,我们需要设置一个本地Web服务器来提供这些文件。解决方案步骤:1.安装本地Web服务器:可以选择轻量级的Web服务器,例如Python内置的HTTP服务器、Node.js的http-server、或者Apache/Nginx等。2.启动Web服务器并指向Unity构建的目录:以Python为例,在Unity构建的目录(包含index.html和Build文件夹的目录)中运行一个简单的HTTP服务器。3.通过localhost访问:在浏览器中访问http://localhost:端口号来加载Unity内容。详细步骤:方法一:使用Python内置HTTP服务器(适用于安装了Python的环境)-打开命令行(终端),进入Unity构建输出的目录(即包含index.html的目录)。-运行命令:python-mhttp.server8000或者,如果你使用的是Python2.x,则使用:python -m SimpleHTTPServer8000-然后在浏览器中访问:http://localhost:8000方法二:使用Node.js的http-server-首先确保安装了Node.js,然后全局安装http-server:npminstall -g http-server-在Unity构建输出的目录中运行:http-server -p8000-然后在浏览器中访问:http://localhost:8000方法三:使用其他Web服务器(如Apache、Nginx)-配置服务器根目录为Unity构建输出的目录,并启动服务器。为什么需要这样做?因为浏览器对于file://协议有安全限制,不允许加载某些类型的文件(比如.data.br文件)或进行跨域请求。使用本地Web服务器可以模拟真实的Web环境,避免这些限制。另外,如果用户正在使用Unity Editor进行测试,建议使用UnityEditor的Play模式或者使用Unity自带的本地服务器(在Build&Run时Unity会自动启动一个本地服务器)。如果用户已经将内容部署到远程服务器,但仍然遇到此问题,则可能是路径配置问题或服务器未正确配置MIME类型。但根据当前错误,问题在于本地使用file://协议,因此设置本地服务器是最直接的解决方案。注意事项:-确保Web服务器正确配置了MIME类型,特别是对于.br文件(Brotli压缩文件)需要添加正确的MIME类型。但通常现代浏览器可以自动处理,如果遇到文件类型无法识别,可以配置服务器:.br文件类型对应的MIME类型为:application/x-brotli但注意,实际上Unity WebGL生成的文件中,.br文件是预压缩的,服务器应该配置为在发送.br文件时同时设置Content-Encoding为br,并且设置正确的Content-Type(根据原始文件类型,比如.data.br的原始文件是二进制数据,可以设置为application/octet-stream)。不过,大多数简单服务器(如Python的http.server)可能不需要特别配置,因为浏览器可以处理。但是,在Python的http.server中,默认可能不会识别.br文件。如果遇到服务器没有正确发送Content-Encoding的情况,可能需要自定义一个简单的服务器脚本。不过,UnityWebGL在加载时会根据文件扩展名自动处理,所以通常只要服务器能提供文件,浏览器就能正确加载。如果用户遇到加载失败,可以检查浏览器的开发者工具(Network选项卡)查看文件是否被正确下载,以及响应头是否正确。生成相关问题:1.如何配置Apache服务器来提供Unity WebGL内容?2.为什么UnityWebGL构建在本地文件系统中无法运行?3.如何解决UnityWebGL构建中的跨域问题?4.除了本地服务器,还有其他方法测试Unity WebGL内容吗?5. UnityWebGL构建中不同文件的作用是什么?根据以上分析,我们给出回答。</think>### 解决Unity WebGL文件加载失败问题 当出现错误 `Failed to download file Build/unityBuild.data.br` 时,核心原因是浏览器安全策略禁止通过 `file://` 协议加载压缩资源文件。以下是完整解决方案: #### 解决方案步骤 1. **安装本地Web服务器**(任选其一): - **Python内置服务器**(推荐): ```bash # 进入Unity构建目录(包含index.html的文件夹) cd path/to/your/unity_build # 启动服务器(Python 3) python -m http.server 8000 ``` - **Node.js http-server**: ```bash npm install -g http-server http-server -p 8000 -c-1 # -c-1禁用缓存 ``` 2. **通过Web服务器访问**: 在浏览器中打开 `http://localhost:8000` 而非本地HTML文件 3. **验证服务器配置**: - 确保服务器能正确发送 `.br` 文件的MIME类型: ```http Content-Type: application/x-brotli Content-Encoding: br ``` - 检查浏览器开发者工具(Network选项卡)确认文件成功加载 #### 根本原因说明 - 浏览器安全限制:`file://` 协议会阻止加载压缩资源(如 `.br`)和跨域请求 - Unity WebGL特性:构建后的资源需通过HTTP协议加载,且需要正确的MIME类型[^1] - 压缩文件要求:`.data.br` 是Brotli压缩的二进制资源,必须由服务器解压传输 #### 替代方案 如果无法安装服务器: 1. **使用Unity开发服务器**: - 在Unity Editor中执行 `Build & Run`(Ctrl+B) - Unity会自动启动本地服务器 2. **修改构建设置**(临时方案): ```csharp // 在Unity编辑器中取消压缩 Player Settings > Publishing Settings > Compression Format = Disabled ``` > 注意:这会增大加载文件体积,仅用于临时测试 #### 故障排查 | 现象 | 解决方案 | |------|----------| | 404文件未找到 | 检查服务器是否指向包含`Build/`文件夹的目录 | | MIME类型错误 | 添加服务器配置:`.br = application/x-brotli` | | 缓存问题 | 使用`http-server -c-1`或浏览器强制刷新(Ctrl+F5) | --- ### 相关问题 1. 如何配置Apache/Nginx服务器部署Unity WebGL内容? 2. Unity WebGL构建中不同压缩格式(Brotli/Gzip)有何性能差异? 3. 浏览器安全策略如何影响WebGL应用的本地测试? 4. 除了本地服务器,还有哪些方法可以测试Unity WebGL构建? 5. 如何通过Chrome开发者工具调试Unity WebGL资源加载问题? > 引用说明:本地服务器配置要求参考Unity WebGL部署文档[^1],MIME类型设置参考MDN Web文档标准[^2]。 [^1]: Unity官方明确要求通过HTTP服务加载WebGL资源,file://协议仅支持基础HTML [^2]: Brotli压缩格式需要正确的Content-Encoding标头,否则浏览器无法解码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鱼蛋-Felix

如果对你有用,可以请我喝杯可乐

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值