MVC捆绑和缩小:将嵌入的图像转换为URL路径

28

在我的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。

4个回答

14

1
请参见我的答案,其中包含一个修复程序的 NuGet 包,可快速安装。 - benmccallum

8

6
如果您不想将嵌入的图像提取为实际文件,并且您不能等待Microsoft.AspNet.Web.Optimization nuget的新版本,您可以使用以下类。它是CssRewriteUrlTransform的逐字复制,但它忽略了使用数据URI语法的URL(粗略地说)。代码片段: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);
    }
}

不错!向他们发送一个拉取请求,这将对整个社区有很大的好处! - trailmax
7
抱歉,但它不起作用。它将"url('data:image" 转换为没有前缀 "url(" 的"data:image"。另一方面,异常逻辑应该在RebaseUrlToAbsolute而不是ConvertUrlsToAbsolute中执行。这个类对我来说有效:https://github.com/benmccallum/AspNetBundling/blob/master/AspNetBundling/CssRewriteUrlTransformFixed.cs - Subgurim

1

我们在 asp.net mvc 和 angular 项目中遇到了同样的问题。问题出现在 ag-grid 的 base64 图片在生产环境中无法显示。

为了解决这个问题,我们采用了一个变通方法,即删除 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...)

在进行了上述更改后,base64图像没有附加任何路径。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接