抓取網頁內容、郵件模板處理、內容遷移等場景中,HTML 原始碼常包含相對路徑(/images/logo.png、../style.css),直接使用會導致資源載入失敗。需將其轉換為完整絕對 URL。
using System;
using System.IO;
using mshtml; // 需參考 Microsoft.mshtml (COM: Microsoft HTML Object Library)
public static string ConvertToAbsoluteUrls(string html, Uri baseUri)
{
// 建立 DOM 文件
var doc = new HTMLDocumentClass();
doc.write(html);
doc.close();
// 處理所有錨點連結
foreach (IHTMLAnchorElement anchor in doc.links)
{
var element = (IHTMLElement)anchor;
string href = (string)element.getAttribute("href", 2); // 2 = 不取預設值
if (!string.IsNullOrEmpty(href))
{
var absoluteUri = new Uri(baseUri, href);
anchor.href = absoluteUri.AbsoluteUri;
}
}
// 處理所有圖片來源
foreach (IHTMLImgElement img in doc.images)
{
var element = (IHTMLElement)img;
string src = (string)element.getAttribute("src", 2);
if (!string.IsNullOrEmpty(src))
{
var absoluteUri = new Uri(baseUri, src);
img.src = absoluteUri.AbsoluteUri;
}
}
return doc.body.innerHTML;
}
new Uri(baseUri, relativeUri) 正確處理 ./、../、/、協定相對路徑(//cdn.example.com)等所有相對路徑形式2 表示取得原始屬性值,不進行瀏覽器預設行為處理.NET Core / .NET 5+ 專案建議使用 HtmlAgilityPack 或 AngleSharp 等純 managed HTML 解析器,避免 COM 相依性,支援跨平台部署:
// HtmlAgilityPack 範例
var doc = new HtmlDocument();
doc.LoadHtml(html);
foreach (var node in doc.DocumentNode.SelectNodes("//a[@href] | //img[@src]"))
{
string attrName = node.Name == "a" ? "href" : "src";
string relative = node.GetAttributeValue(attrName, "");
if (!string.IsNullOrEmpty(relative))
node.SetAttributeValue(attrName, new Uri(baseUri, relative).AbsoluteUri);
}
return doc.DocumentNode.OuterHtml;