Объединение и минимизация MVC: конвертирует внедренные изображения в URL-пути
В моем проекте MVC5.1 я использую связывание и минимизацию с преобразованием перезаписи CSS:
styleBundle.Include("~/Content/Site.css", new CssRewriteUrlTransform());
bundles.Add(styleBundle);
CssRewriteUrlTransform
преобразует пути изображения относительно корня сайта. Но когда я вставлял изображения в css:
span.file {
background-image: url(data:image/png;base64,iVBORw0KGg+...2AAAAElFTkSuQmCC);
}
это переводится в
span.file {
background-image: url(http://localhost:52253/Content/data:image/png;base64,iVBORg...mCC);
}
И, очевидно, ~/Content/data:image/png;base64...
не существует.
Любой способ остановить это, кроме обновления файлов CSS, чтобы не включать внедренные изображения? Или разделить на разные CSS файлы, где с использованием фактического URL-адреса и URL-преобразования этих файлов. И еще один css с только встроенными изображениями.
Ответы
Ответ 1
Отбросьте этот вопрос. Это известная ошибка. В настоящее время мы работаем над тем, чтобы разделить ваш CSS на встроенные изображения и изображения с помощью URL.
Голосовать за эти рабочие элементы: https://aspnetoptimization.codeplex.com/workitem/88 и https://aspnetoptimization.codeplex.com/workitem/108
Ответ 2
Если вы не хотите извлекать внедренные изображения в фактические файлы, и вы не можете дождаться появления новой версии пакета Microsoft.AspNet.Web.Optimization nuget, вы можете использовать следующий класс.
Это дословная копия CssRewriteUrlTransform, за исключением того, что она игнорирует (грубо;)) URL-адрес с синтаксисом URI данных.
Gist: https://gist.github.com/janv8000/fa69b2ab6886f635e3df
/// <remarks>Part of Microsoft.AspNet.Web.Optimization.1.1.3, forked to ignore data-uri</remarks>
public class CssRewriteUrlTransformIgnoringDataUri : IItemTransform
{
internal 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 = baseUrl + "/";
return VirtualPathUtility.ToAbsolute(baseUrl + url);
}
internal static string ConvertUrlsToAbsolute(string baseUrl, string content)
{
if (string.IsNullOrWhiteSpace(content))
{ return content; }
return new Regex("url\\(['\"]?(?<url>[^)]+?)['\"]?\\)").Replace(content, match =>
{
var format = match.Groups["url"].Value;
if (format.StartsWith("data:image", StringComparison.CurrentCultureIgnoreCase))
{
return format;
}
return "url(" + RebaseUrlToAbsolute(baseUrl, format) + ")";
});
}
public string Process(string includedVirtualPath, string input)
{
if (includedVirtualPath == null)
{
throw new ArgumentNullException("includedVirtualPath");
}
return ConvertUrlsToAbsolute(VirtualPathUtility.GetDirectory(includedVirtualPath.Substring(1)), input);
}
}
Ответ 3
Оформите мой обходной путь, который я аккуратно "упаковал" в пакет NuGet. https://github.com/benmccallum/AspNetBundling
В противном случае просто обновитесь до grunt/gulp;)
Ответ 4
Мы столкнулись с той же проблемой для asp.net mvc с угловым проектом. Проблема была для изображения ag-grid base 64, которое не показывалось в среде prod.
В качестве обходного пути мы удалили CssRewriteUrlTransform() и изменили виртуальный путь, чтобы он соответствовал фактическому физическому пути.
Old code
bundles.Add(new StyleBundle("~/bundles/styles").Include("~/Content/Site.css", new CssRewriteUrlTransform());
New code change
bundles.Add(new StyleBundle("~/dist/styles").Include("~/Content/Site.css");
Изначально в образе base64 искалась папка bundles, которой не было.
Old
background: transparent url(data:image/svg+xml;base64,PHN2ZyB3a...)
был переведен в
background: transparent url(/dist/data:image/svg+xml;base64,PHN2ZyB3a...)
После внесения упомянутых изменений в базовое изображение 64 не было добавлено ни одного пути.