【问题标题】:ASP.NET Bundling - Bundle not updating after included file has changed (returns 304 not modified)ASP.NET 捆绑 - 包含的文件更改后捆绑不更新(返回 304 未修改)
【发布时间】:2023-04-08 20:47:01
【问题描述】:

我正在尝试 ASP.NET 捆绑与 ASP.NET MVC 4 应用程序。情况是我想做一个 CDN 样式的服务,它有 JS 和 CSS 文件,你可以从其他站点使用这种类型的地址寻址到它们:http://www.mycdn.com/scripts/plugin/js,它捆绑并缩小了所有包含的 .js 文件。

我的一个文件的捆绑配置如下所示:

bundles.Add(new ScriptBundle("~/Scripts/plugin/pluginjs").Include("~/Scripts/plugin/jquery.plugin.js"));

但是,当我这样做时,即使我更改了原始 js 文件,捆绑包也没有得到更新。当我刷新浏览器时,我不断收到 304 Not Modified,并且缩小文件的内容没有更新。我怎样才能使包更新,因为旧内容的包是没用的?我尝试了各种方法,但无法找到解决方案。

提前致谢!

【问题讨论】:

  • 请参阅stackoverflow.com/a/34508048/1545567 以获得该问题的可能答案(即使用来自其他站点或纯 html 的捆绑包)
  • 触摸普通文件和缩小文件,它会重新加载它们。

标签: asp.net bundle asp.net-optimization bundling-and-minification


【解决方案1】:

我刚刚遇到了完全相同的问题。我有一个包含 2 个 CSS 文件的文件夹:

  • ~/Content/main.css
  • ~/Content/main.min.css(在我之前的手动缩小过程中已经存在)

我的捆绑代码是这样的:

bundles.Add(new StyleBundle("~/css/main").Include("~/content/main.css"));

无论我如何更改我的main.css,输出都是具有相同内容的相同网址:

<link href="/css/main?v=6Xf_QaUMSlzHbXralZP7Msq1EiLTd7g1vId6Vcy8NJM1" rel="stylesheet"/>

更新捆绑包的唯一方法是重建我的解决方案 - 显然不是最好的方法。

但是我一删除main.min.css,一切都开始正常了。 再玩一点我发现如果main.cssmain.min.css 都有,然后更新@987654329 @ 实际上会更新捆绑包...很奇怪,但至少可以预测。

【讨论】:

  • documentation 捆绑框架遵循几个常见的约定,例如: 当存在“FileX.min.js”和“FileX.js”时选择“.min”文件进行发布。选择非“.min”版本进行调试。忽略仅由 IntelliSense 使用的“-vsdoc”文件(例如 jquery-1.7.1-vsdoc.js)。
  • 请参阅stackoverflow.com/a/14967754/682105,了解如何配置忽略列表。
  • 这解决了问题...非常好的答案...感谢在我奇怪的情况下我有一个 main.js 和一个 main.min.remove.js (它拿起了 main.js min.remove.js)我清理的其他人的技术债务,一切都很甜蜜
  • 我觉得 Microsoft 决定忽略我仔细编码的捆绑包而只使用同一目录中包含的任何“min”文件,这很荒谬。如果我想使用“min”文件,我会指定“min”文件。 FFS。
  • @felickz 谢谢,这是一个奇怪的问题,虽然行为是有道理的,但我没想到。我不得不修补一个库并且没有手动更新 .min.js 文件,因为 .js 文件包含在包中。
【解决方案2】:

在努力弄清楚包缓存刷新的原因之后,我得出了一些希望对其他人有所帮助的结论:

如果 .min 文件包含在捆绑包中:

  • 发布模式 + 更改最小 js 代码 = 缓存刷新
  • 发布模式 + 更改非 min js 代码 = 无缓存刷新
  • 调试模式 + 更改最小 js 代码 = 无缓存刷新
  • 调试模式 + 更改非最小 js 代码 = 无缓存刷新

如果 .min 文件不包含在包中:

  • 调试模式 + 更改 js 代码 = 无缓存刷新
  • 发布模式+更改js代码=缓存刷新

注意事项

  • 调试模式是指 web.config 编译 debug = true (和 BundleTable.EnableOptimizations = false 或被省略)
  • 发布模式是指 web.config 编译 debug = false(和 BundleTable.EnableOptimizations = true 或被省略
  • 确保您确实在进行代码更改。空格等变化 并且 cmets 不会影响生成的缩小 js,因此服务器是 正确之处在于没有更改(因此捆绑缓存不是 刷新)。

【讨论】:

  • 如果我们在调试模式下发布呢?这是否意味着捆绑将在生产中被破坏——总是在 IIS 重新启动后交付它创建的第一个捆绑包?
  • 如果您还设置了 BundleTable.EnableOptimizations = true,您仍然可以将捆绑与 web.config debug="true" 一起使用
【解决方案3】:

请注意,如果您使用的是 Google Chrome,缓存会非常激进。为确保没有缓存任何内容,您可以执行 Ctrl-Shift-I 来调出开发人员窗格。转到Network 并单击Disable Cache。确保您保持打开状态。现在刷新页面。您的缓存应该被清除,并且文件更改现在应该反映。

【讨论】:

    【解决方案4】:

    好的,这是我的故事。我禁用了 Web Essentials 中较少文件的最小文件生成。旧的 min 文件没有被删除,并且 bundle thingy 看到的是那些而不是更新的 CSS。祝你好运!

    编辑

    不久之后,我又在同一个问题上花了 2 个小时。这一次我猜是我的错 - 我忘记了领先的波浪号,即我写了

    Scripts.Render("/js/script")
    

    代替

    Scripts.Render("~/js/script")
    

    无论出于何种原因,它有时会奏效,有时却没有。

    【讨论】:

    • 删除 .min 文件也为我解决了捆绑问题。在我的情况下,它可能发生在分支之间合并之后。
    • 这对我也有用,但是任何已知的结果为什么“~”不起作用。
    【解决方案5】:

    我实际上决定不使用 System.Web.Optimization 来完成这项任务,但我发现了 Microsoft Ajax Minifier,它也包含在 WebGrease.dll 中,它与 MVC4 System.Web.Optimization 库一起提供。我编写了以下函数,然后在 Application_Start 中为每个缩小的文件调用该函数:

        public static void MinifyFile(string virtualPath)
        {
            string fullPath = HttpContext.Current.Server.MapPath(virtualPath);
            string extension = Path.GetExtension(fullPath).ToLower();
            string targetPath = fullPath.Substring(0, fullPath.Length - extension.Length) + ".min" + extension;
            if(File.Exists(fullPath) == false) 
            {
                throw new FileNotFoundException("File not found: " + fullPath);
            }
            string input = File.ReadAllText(fullPath);
            string output;
            if (extension == ".js")
            {
                Microsoft.Ajax.Utilities.Minifier jsmin = new Microsoft.Ajax.Utilities.Minifier();
                output = jsmin.MinifyJavaScript(input);
            }
            else if (extension == ".css")
            {
                Microsoft.Ajax.Utilities.Minifier jsmin = new Microsoft.Ajax.Utilities.Minifier();
                output = jsmin.MinifyStyleSheet(input);                
            }
            else
            {
                throw new NotSupportedException(extension + " is not supported for minification.");
            }
            File.WriteAllText(targetPath, output);
        }
    

    现在,我的应用程序正在缩小 Application_Start 上的所有文件。

    【讨论】:

    • 所以您没有找到任何解决方案。我遇到了同样的问题,更改了css文件中的背景图片,在开发站中调试效果很好,发布后,出现旧背景。没有更新缩小文件。 :(
    【解决方案6】:

    捆绑操作区分大小写。确保文件名大小写正确。

    我必须在我的 BundleConfig.cs 中更改一行:

    bundles.Add(new StyleBundle("~/Content/css").Include(
        "~/Content/bootstrap.css",
        "~/Content/Site.css"));  <-- Uppercased.
    

    【讨论】:

      【解决方案7】:

      我不确定目前的功能是否真的支持成为 CDN,因为它隐式依赖 url 来包含哈希码以防止浏览器缓存。

      但是我可以尝试帮助您尝试到达那里,也许今天就可能实现... 一个可能成为障碍的问题是 BundleHandler 将在任何包含 IfLastModified 标头的捆绑请求上返回 304,因为假设是由于url中的指纹,浏览器缓存始终有效。

      您能否添加一些有关如何呈现对捆绑包的引用的详细信息?你在使用类似 Scripts.Render("~/Scripts/plugin/pluginjs") 的东西吗?

      你的捆绑脚本标签应该是这样的:

      Good: <script src="/fbt/bundles/js?v=wvLq7H7qEZB2giyIRn7aEZAxhHOb2RfTYYh2HMd9EqM1"></script>
      

      如果您的脚本标签引用了没有版本字符串的原始包,这可能会解释您看到的缓存问题:

      Not good: <script src="/fbt/bundles/js></script>
      

      【讨论】:

      • 问题是这是一个CDN类型的服务,所以它是为其他网站托管文件,它本身并不使用这些文件。因此,引用站点可以是任何东西,不一定是 ASP.NET 站点。我还发现 Bundling 有一个叫做 CDN 支持的东西。
      • asp.net/mvc/tutorials/mvc-4/bundling-and-minification(参见 CDN 部分)是否有可能我只是正常托管文件而不进行捆绑和缩小,然后可能使用 CDN 格式从其他 ASP.NET 站点引用这些文件: bundles.UseCdn = true; //启用 CDN 支持 string cdnPath = "mycdn.com/scripts/plugin/myplugin-x.y.z.min.js"; bundles.Add(new ScriptBundle("~/bundles/jquery", cdnPath).Include("~/Scripts/myplugin-{version}.js"));
      • 是的,如果这是一个可行的选择,那么这很可能是最好的选择,只需让 ASP.NET 站点使用托管捆绑包的 CDN。
      【解决方案8】:

      我知道它已经更新了一段时间,但我发现我只需要等待几秒钟就可以让包赶上我的 css 更改。我将引导程序较少的文件编译成 css 和 min.css,而且绝对不能立即看到我的更改。对我来说,在带有 ssd 的快速电脑上大约需要 10 秒。您的里程可能会因您的系统规格而异。

      【讨论】:

        【解决方案9】:

        我看到了这个答案,但这些都不是我的情况。 有一些 CSS 规则使样式捆绑器失败并且我得到相同的哈希,即使我对 CSS 文件进行了更改。以前对我来说一切正常。

        在我的例子中,违反 css 选择器规则是 -

        #globalSearch.searching { ... }
        

        如果我只是这样做了

        .searching { ... }
        

        一切都重新开始工作,我对我的 css 文件所做的任何更改,捆绑器哈希都会正确更改。 只需添加此答案,因为它可能会对某人有所帮助。

        【讨论】:

          【解决方案10】:

          只需通过 NuGet 更新您的 System.Web.Optimization

          【讨论】:

            【解决方案11】:

            不管怎样,我刚才遇到了同样的问题,一个 js 文件无论如何都莫名其妙地拒绝更新(重建、强制清除缓存等)。过了一会,我打开IE中的客户端调试工具(F12)开始观察网络流量,仅此行为就强制刷新JS文件。想想看,但它奏效了。

            【讨论】:

              【解决方案12】:

              对我来说,问题是我让 Fiddler 运行。在我关闭 dit 并重建我的解决方案后,它正在为我加载 js 文件中的更改。

              【讨论】:

                【解决方案13】:

                我遇到了类似的问题。在我的情况下,我在样式包中引用了一个 CSS 文件,并在我的 MVC 视图中引用了该包。我还在捆绑代码中将“EnableOptimizations”标志设置为 false。

                尽管如此,视图拒绝更新以包含新的 CSS 文件。

                我的解决方案是创建一个缩小版的 CSS 文件并将其包含在项目中,然后它就开始工作了。我不知道为什么会出现这种情况,因为该缩小文件在任何地方都没有被引用(即使在视图更新之后),甚至不应该考虑,因为代码被设置为不被优化。这很可能是捆绑功能的错误(或功能)。我希望这可以帮助其他遇到此问题的人。

                【讨论】:

                  【解决方案14】:

                  确保您的应用确实在发布模式下部署,并且您的主机正在摆弄设置。我遇到了这个问题,但经过调查,我意识到我的文件实际上并没有被捆绑。我在发布模式下部署,但由于某种原因(我怀疑是主机),我认为我的应用程序实际上是在调试中部署的。

                  我必须在 BundleConfig.cs 文件的末尾设置以下内容以强制捆绑,这反过来又强制更新的文件最终显示在浏览器中。

                  BundleTable.EnableOptimizations = true;
                  

                  【讨论】:

                    【解决方案15】:

                    我今天遇到了这个问题,我浏览了所有答案,但这里的任何解决方案都没有解决我的问题。后来我发现这是因为我的 CSS 中有错误。其中一个网址未关闭(缺少最后一个单引号)。

                    这导致 css 文件出现语法错误,并且无法针对 Bundleconfig 进行编译。我想输出日志中会有一条消息,但我没有检查。

                    如果您在 2020 年遇到这种情况,请尝试确保您的 CSS 没有语法错误。

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 2017-02-11
                      • 1970-01-01
                      • 1970-01-01
                      • 2021-07-23
                      • 1970-01-01
                      • 2016-01-26
                      • 1970-01-01
                      相关资源
                      最近更新 更多