Uri.IdnHost 不適用于長主機。這是正常行為嗎?如何解決這個問題?
void checkIDN(string urlString)
{
var uri = new Uri(urlString);
Console.WriteLine($"{uri.Host,-40} ---> {uri.IdnHost}");
}
checkIDN("https://единая-дата-объединения-застройщиков.рф");
checkIDN("https://единая-дата-объединения-застройщико.рф");
checkIDN("https://единая-дата-объединения-застройщик.рф");
checkIDN("https://единая-дата-объединения-застройщи.рф");
checkIDN("https://единая-дата-объединения-застройщ.рф");
checkIDN("https://единая-дата-объединения-застрой.рф");
checkIDN("https://единая-дата-объединения-застро.рф");
uj5u.com熱心網友回復:
作為參考,您的代碼會產生以下結果:
единая-дата-объединения-застройщиков.рф ---> единая-дата-объединения-застройщиков.рф
единая-дата-объединения-застройщико.рф ---> единая-дата-объединения-застройщико.рф
единая-дата-объединения-застройщик.рф ---> единая-дата-объединения-застройщик.рф
единая-дата-объединения-застройщи.рф ---> единая-дата-объединения-застройщи.рф
единая-дата-объединения-застройщ.рф ---> единая-дата-объединения-застройщ.рф
единая-дата-объединения-застрой.рф ---> xn------5cdbacgvcedib5aejbw8dkbql3czamp4tlfqa.xn--p1ai
единая-дата-объединения-застро.рф ---> xn------5cdbacgvcedib5aejb7fkbpl1cyalp6s6eqa.xn--p1ai
請注意,只要主機名中“.рф”之前的部分超過 31 個字符 - 它就會按預期停止作業。
RFC 規定的域名最多可包含 256 個字符,每個標簽(標簽以點分隔)最多可包含 63 個字符。對于 IDN 名稱,雖然我們不應該直接計算字符數,而是計算已轉換名稱中的字符數。
但是,根據我在 .NET 源代碼中找到的這段代碼,如果標簽包含 unicode 字符 - 它只會將每個 unicode 字符計為 2:
count ;
if (*newPos > 0xFF)
count ; // counts for two octets
然后它進行檢查:
if (... (labelHasUnicode ? count 4 : count) > 63 ...)
{
return false;
}
長話短說 - 它不認為您的域名是有效的,因為它認為違反了標簽長度要求。如果它不是有效的域名 - 無需將其轉換為 IDN。您可以通過運行來驗證它不認為它是一個有效的域名:
Uri.CheckHostName("единая-дата-объединения-застройщиков.рф");
這將回傳“未知”,而對于有效域名,它將回傳“Dns”。
我可能會錯過一些東西,但我不同意這一點,因為如果我們轉換標簽“единая-дата-объединения-застройщиков”,我們將得到這個字串:
XN------5CDBACGLLCEEIB7AFJBDUX5CKBTLD7C3AQP8USA0OQA
它包含 51 個字符,因此不違反要求,因此整個內容都是有效的域名。
我會在 .NET 錯誤跟蹤器中提交一個錯誤來描述該問題,也許他們可以更好地澄清。
作為一種解決方法,您可以使用IdnMapping類:
static void checkIDN(string urlString) {
var uri = new Uri(urlString);
var m = new IdnMapping();
var idn = m.GetAscii(uri.Host);
Console.WriteLine($"{uri.Host,-40} ---> {idn}");
}
此類不進行任何檢查,只是將字串轉換為 IDN。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/530288.html
