【发布时间】:2014-09-09 01:30:17
【问题描述】:
我使用 ASP.NET Web 优化包来捆绑和缩小 javascript/css 文件。
我有几个 ASP.NET 应用程序使用相同的 javascript/css 文件,现在我在每个应用程序中设置包。
我想知道是否有一种方法可以在其中一个应用程序中注册捆绑包,而其他应用程序只是使用它。
关键问题是如何在其他应用程序中获取查询字符串的哈希码,而不是注册捆绑包的应用程序。
【问题讨论】:
我使用 ASP.NET Web 优化包来捆绑和缩小 javascript/css 文件。
我有几个 ASP.NET 应用程序使用相同的 javascript/css 文件,现在我在每个应用程序中设置包。
我想知道是否有一种方法可以在其中一个应用程序中注册捆绑包,而其他应用程序只是使用它。
关键问题是如何在其他应用程序中获取查询字符串的哈希码,而不是注册捆绑包的应用程序。
【问题讨论】:
我认为这是不可能的。好吧,没有什么能阻止您从外部应用程序渲染样式和脚本包。您可以使用本机 script 标记并指定绝对 url 手动拉取捆绑的资源...
<script src="http://domain.com/bundles/jquery"></script>
或者在 razor 中使用 Scripts.Render 助手...
@Scripts.Render("http://domain.com/bundles/jquery")
但是,如果资源服务器更改这些样式/脚本包的内容,您将遇到缓存问题,因为消费应用程序将无法解析缓存查询字符串。它无法解决的原因似乎很明显......Scripts.Render 帮助程序使用当前应用程序的 Web 优化框架来呈现缓存查询字符串,但是,消费应用程序使用不同的 Web 优化框架实例。
我不知道这是如何在幕后工作的,我唯一确定的是缓存查询字符串会在捆绑内容(文件)更改时发生更改。我猜缓存查询字符串使用某种基于机器键值或其他东西的散列算法......这只是我的猜测,但如果你热衷于获取源代码,你当然可以查看源代码这个底部...
http://aspnetoptimization.codeplex.com/SourceControl/latest
因为对于这些问题似乎没有任何解决方法,如果您的项目有一个外部资源服务器来为其他应用程序提供通用样式和脚本是至关重要的。我只需按上述方式手动访问它们,并通过在捆绑名称末尾附加一个数字来对资源进行版本控制...
@Scripts.Render("http://server.com/bundles/name1")
并在每次更新资源时更新您的应用程序以引用正确的版本,以避免浏览器呈现旧的缓存版本。
另一种方法(不会为上述方法带来任何新内容)是实现您自己的优化例程,这似乎并不难。如果您需要,它可能会提供一些灵活性。看看这个Ayende's article...确保你也阅读了 cmets
就我个人而言,我不喜欢他将文件名附加到查询字符串的方式,但是,您实际上不必这样做,只要您能够解析捆绑包的 url。
【讨论】:
您可以通过以下方式完成此操作,但代价是在其他应用程序中这些已被优化,而不是像在调试版本中使用捆绑时那样一一进行。
假设您在定义了所有捆绑包的应用程序中创建了一个新的 CDNController 类:
public class CDNController : Controller {
public ActionResult Script(string id)
{
string url = BundleTable.Bundles.ResolveBundleUrl(string.Format("~/bundles/{0}", id));
if (string.IsNullOrEmpty(url))
{
return HttpNotFound();
}
return Redirect(url);
}
}
您需要使用捆绑 ID 调用操作方法。如果你通常会写:
@Scripts.Render("~/bundles/jquery)
您需要将其替换为对新操作方法的调用。如果托管/主应用程序安装在 `/mainapp' 的应用程序路径下,您将编写:
<script src="/mainapp/CDN/Script/jquery"></script>
与第一种方式不同,这不需要您在其他应用程序中注册捆绑包,它只需要您编写绝对路径。新的操作方法请求捆绑 url(包括神秘的哈希)并重定向到该地址。例如,它可以重定向到:/mainapp/bundles/frameworks?v=pznFYVbTrRKNlRAgSb6KWMMjBI0qJjNleRyztT6W1gU1。此地址将始终将包缩小并捆绑在一起。
您也可以创建类似的操作方法来呈现 CSS 包。
【讨论】:
你可以这样做:
var domain="http://www.google.com";
Styles.DefaultTagFormat = "<link href=\"" + domain + "{0}\" rel=\"stylesheet\"/>";
Scripts.DefaultTagFormat = "<script src=\"" + domain + "{0}\" type=\"text/javascript\"></script>";
当你打电话时:
Styles.Render("~/masterpagecss")
Scripts.Render("~/masterpagejstop")
这将呈现如下:
<link href="http://www.google.comm/masterpagecss?v=cUYMJ2uO6cjidXEjFnWzUVvVS4_GR9OGA45p3oKZJSQ1" rel="stylesheet"/>
<script src="http://www.google.com/masterpagejstop?v=Oay1Ofn63qSMuPEhfoMe9tPsA_Hp9HeG2rAEcaA6RWk1"></script>
我在我的网站上试过了,效果很好。
只需确保您使用的域是您网站的绑定,因为我们可以访问这些文件。
【讨论】:
bundles.Add(new StyleBundle("~/Content/css", "http://cdn-site.com/Content/css")。有关我的问题的更多详细信息:stackoverflow.com/questions/48179363/…)