我们在我们的网站中使用MVC捆绑,CssRewriteUrlTransform
确保图像URL从动态捆绑CSS文件工作。
但这仅在不使用虚拟目录时才有效,即
http://localhost/VirttualDir
不起作用,但http://localhost/
起作用。这是因为CssRewriteUrlTransform
转换在重写 url 时不会考虑虚拟文件夹。因此,如果localhost/vdir/content/img/foo.png
图像真实路径,它将重写它以localhost/content/img/foo.png
这是错误的
我不确定是否完全理解您的问题,但在这里看到http://localhost
似乎是错误的。切勿为捆绑包使用绝对 URL。
对我来说,CssRewriteUrlTransform完美地工作,这是我如何使用它:
bundles.Add(new StyleBundle("~/bundles/css").Include(
"~/Content/css/*.css", new CssRewriteUrlTransform()));
"捆绑包"是虚拟的。
这有帮助吗?
更新
我对"VirtualDir"这个东西感到困惑,因为你在谈论IIS VirtualDir,我在想Bundle VirtualDir!确实,在这种情况下,CssRewriteUrlTransform会将URL重写到主机,而不是Host/VirtualDir URI。
要做到这一点,你必须派生CssRewriteUrlTransform,让它做你需要的事情。这里有一个很好的讨论:ASP.NET MVC4与Twitter引导程序捆绑在一起
似乎最好的答案是:http://aspnetoptimization.codeplex.com/workitem/83
public class CssRewriteUrlTransformWrapper : IItemTransform
{
public string Process(string includedVirtualPath, string input)
{
return new CssRewriteUrlTransform().Process("~" + VirtualPathUtility.ToAbsolute(includedVirtualPath), input);
}
}
使用此类代替 CssRewriteUrlTransform
我遇到了同样的问题。这就是我修复它的方式:
private class ProperUrlRewrite : IItemTransform
{
private static string RebaseUrlToAbsolute(string baseUrl, string url)
{
if (string.IsNullOrWhiteSpace(url) || string.IsNullOrWhiteSpace(baseUrl) || url.StartsWith("/", StringComparison.OrdinalIgnoreCase) || url.Contains(':'))
return url;
return VirtualPathUtility.Combine(baseUrl, url);
}
private static Regex UrlPattern = new Regex("url\s*\(['"]?(?<url>[^)]+?)['"]?\)");
public string Process(string includedVirtualPath, string input)
{
if (includedVirtualPath == null)
throw new ArgumentNullException("includedVirtualPath");
if (string.IsNullOrWhiteSpace(input))
return input;
string directory = VirtualPathUtility.GetDirectory(VirtualPathUtility.ToAbsolute(includedVirtualPath));
if (!directory.EndsWith("/", StringComparison.OrdinalIgnoreCase))
directory += "/";
return UrlPattern.Replace(input, match => "url(" + ProperUrlRewrite.RebaseUrlToAbsolute(directory, match.Groups["url"].Value) + ")");
}
}
我知道它远非完美,并且有很多边缘情况可能会出错(我不确定您是否可以首先使用正则表达式解析 CSS 文件 - 尽管这正是原始CssRewriteUrlTransform
所做的),但到目前为止它成立......
'CssRewriteUrlTransform' 对于不在虚拟目录上运行的应用程序来说效果很好。
因此,如果您的应用程序运行在 http://your-site.com/它运行良好,但如果在 http://your-site.com/your-app/上运行,则所有图像都将有 404,因为默认的"CssFixRewriteUrlTransform"引用带有"/"的图像。
使用这个:
public class CssFixRewriteUrlTransform: IItemTransform {
private static string ConvertUrlsToAbsolute(string baseUrl, string content) {
if (string.IsNullOrWhiteSpace(content)) {
return content;
}
var regex = new Regex("url\(['"]?(?<url>[^)]+?)['"]?\)");
return regex.Replace(content, match = > string.Concat("url(", RebaseUrlToAbsolute(baseUrl, match.Groups["url"].Value), ")"));
}
public string Process(string includedVirtualPath, string input) {
if (includedVirtualPath == null) {
throw new ArgumentNullException("includedVirtualPath");
}
var directory = VirtualPathUtility.GetDirectory(includedVirtualPath);
return ConvertUrlsToAbsolute(directory, input);
}
private static string RebaseUrlToAbsolute(string baseUrl, string url) {
if (string.IsNullOrWhiteSpace(url) || string.IsNullOrWhiteSpace(baseUrl) || url.StartsWith("/", StringComparison.OrdinalIgnoreCase)) {
return url;
}
if (!baseUrl.EndsWith("/", StringComparison.OrdinalIgnoreCase)) {
baseUrl = string.Concat(baseUrl, "/");
}
return VirtualPathUtility.ToAbsolute(string.Concat(baseUrl, url));
}
}
注意:删除所有带有 .min.css 的文件 css,因为如果不这样做,它将无法修复。
我对包含"数据"的 url 有问题,甚至还有一个 url 在另一个 url 中,所以我必须重新做正则表达式,这是我的解决方案:
public string Process(string includedVirtualPath, string input)
{
if (includedVirtualPath == null)
{
throw new ArgumentNullException(nameof(includedVirtualPath));
}
if (string.IsNullOrWhiteSpace(input))
{
return input;
}
var directory = VirtualPathUtility.GetDirectory(includedVirtualPath);
if (!directory.EndsWith("/", StringComparison.OrdinalIgnoreCase))
{
directory += "/";
}
return new Regex(@"urls*(s*(['""]?)(?<scheme>(?:(?:data:)|(?:https?:))?)(?<url>(\1|.)*?)1s*)")
.Replace(input, match => string.Concat(
"url(",
match.Groups[1].Value,
match.Groups["scheme"].Value,
match.Groups["scheme"].Value == "" ?
RebaseUrlToAbsolute(directory, match.Groups["url"].Value) :
match.Groups["url"].Value,
match.Groups[1].Value,
")"
));
}
private static string RebaseUrlToAbsolute(string baseUrl, string url)
{
if (string.IsNullOrWhiteSpace(url) || string.IsNullOrWhiteSpace(baseUrl)
|| url.StartsWith("/", StringComparison.OrdinalIgnoreCase))
{
return url;
}
return VirtualPathUtility.ToAbsolute(string.Concat(baseUrl, url));
}
}
基于正则表达式:在引号之间抓取值