代码之家  ›  专栏  ›  技术社区  ›  Victor Sanchez

使用CSS内联更改HTML以使用数据Url

  •  1
  • Victor Sanchez  · 技术社区  · 7 年前

    在want to中,即时更改类似以下内容的HTML:

    <html><head><style>
    body { 
        background: transparent url(http://example.com/image.gif) no-repeat right bottom;
    }
    </style><head>
    <body>
        <img src="http://example.com/image2.gif"/>
    </body>
    </html>
    

    收件人(URL被剪切):

    <html><head><style>
    body { 
        background: transparent url(data:image/gif;base64,R0lGODlhEAAOALMAAOazToeHh0tLS/...) no-repeat right bottom;
    }
    </style>
    <head>
    <body>
        <img src="data:image/gif;base64,R0lGODlhEAAOALMAAOazToeHh0tLS/...."/>
    </body>
    </html>
    

    现在我使用以下代码:

    private string EmbebedImages(string strHtml)
    {
        var doc = new HtmlAgilityPack.HtmlDocument();
        doc.LoadHtml(strHtml);
    
        foreach (var imgNode in doc.DocumentNode.SelectNodes("//img[@src]"))
        {
        string url = imgNode.Attributes["src"].Value;
        if (url.StartsWith("http"))
        {
            using (var webClient = new WebClient())
            {
            var imageAsByteArray = webClient.DownloadData(url);
            string mimeType = MimeMapping.GetMimeMapping(url);
    
            imgNode.Attributes["src"].Value = "data:" + mimeType + ";base64," +
                Convert.ToBase64String(imageAsByteArray);
            }
        }
        }
    
        return doc.DocumentNode.OuterHtml;
    }
    

    但我的代码忽略了CSS中的URL。

    有没有可能让这个改变变得简单?我尝试了一些css库,但找不到简单的表单。。。

    1 回复  |  直到 7 年前
        1
  •  1
  •   ewwink    7 年前

    你不能用HtmlAgilityPack做到这一点,但是试试看 Regex

    using System.Text.RegularExpressions;
    
    private string EmbebedImages(string strHtml) {
        var htmlString = .......load html string....;
        string currentURL;
    
        var images_url = Regex.Matches(htmlString, @"(?:https?:\/\/.*?\.(gif|png|jpg|jpeg))");
        foreach(var url in images_url) {
            currentURL = url.ToString();
            using(var webClient = new WebClient()) {
                var imageAsByteArray = webClient.DownloadData(currentURL);
                string mimeType = MimeMapping.GetMimeMapping(currentURL);
                string dataURL = "data:" + mimeType + ";base64," + Convert.ToBase64String(imageAsByteArray);
                htmlString = htmlString.Replace(currentURL, dataURL);
            }
        }
    
        return htmlString;
    }
    
        2
  •  0
  •   Sebastian Mendez    6 年前

    虽然这不适用于OP的情况,但如果在Python中希望将URL转换为CSS中的数据URI,我是这样做的:

    import requests
    import re
    import base64
    
    def url_to_base64(url, memo=None):
        if memo is None:
            memo = {}
        if url in memo:
            return memo[url]
        res = requests.get(url)
        mime_type = res.headers['content-type']
        base64_data = base64.b64encode(res.content).decode('utf-8')
        data_url = "data:{};base64,{}".format(mime_type, base64_data)
        memo[url] = data_url
        return data_url
    
    
    def embed_urls(html, memo=None):
        if memo is None:
            memo = {}
        pattern = re.compile(r"url\('(https?://.*?)'\)")
        urls = set(re.findall(pattern, html))
        for url in urls:
            base64_data = url_to_base64(url, memo)
            html = html.replace(url, base64_data)
        return html