在 Delphi 开发中,获取域名主要分为两种核心场景:一是获取本地计算机在网络环境中的完全限定域名(FQDN),二是从复杂的 URL 字符串中解析出目标域名。核心上文归纳是:对于获取本地域名,应优先调用 Windows API 的 GetComputerNameEx 函数以确保获取到标准的 DNS 域名;而对于 URL 解析,推荐使用 Indy 组件库中的 TIdURI 类,该方法比手动字符串分割更具鲁棒性和专业性,能够完美处理协议、端口及路径等复杂情况。

获取本地计算机的完全限定域名
在编写网络服务或客户端应用时,经常需要获取本机的身份标识,许多开发者习惯使用 GetComputerName 函数,但这仅能返回 NetBIOS 名称,而不包含 DNS 后缀,为了获取符合网络标准的完全限定域名(FQDN),server.example.com,必须深入使用 Windows API。
使用 GetComputerNameEx 函数
GetComputerNameEx 是 Windows 提供的标准 API,位于 Winapi.Windows 单元中,它支持多种名称类型,ComputerNameDnsFullyQualified 参数正是我们需要的。
在具体实现中,需要注意缓冲区的动态分配,因为域名的长度是不确定的,初次调用通常用于获取所需的缓冲区大小,第二次调用才是填充数据,这种“两次调用”模式是 Windows API 编程中的经典技巧,能够有效避免缓冲区溢出。
代码实现逻辑如下:
声明所需的常量和函数类型,调用时,先将 Size 设为 0,函数会返回 ERROR_INSUFFICIENT_BUFFER 并通过 Size 返回所需字节长度,程序应分配相应大小的内存(通常使用 StrAlloc 或 GetMem),再次调用函数即可成功获取域名,务必在 try...finally 块中释放内存,防止内存泄漏,这种方法不仅权威,而且兼容性极强,适用于从 Windows XP 到 Windows 11 的所有版本。
从 URL 字符串中解析域名
在处理 HTTP 请求或爬虫开发时,更常见的需求是从一个完整的 URL(如 https://www.example.com:8080/page)中提取出域名 www.example.com,这是 Delphi 网络编程中的高频操作。
推荐方案:使用 Indy 的 TIdURI 类

虽然可以使用 Pos 和 Copy 函数进行手动分割,或者使用正则表达式,但这些方法在处理边缘情况(如包含用户名密码的 URL、默认端口省略、非标准字符)时往往力不从心。Indy(Internet Direct)是 Delphi 最成熟的开源网络协议库,其 IdURI 单元提供了专业的 URI 解析能力。
TIdURI 类会自动将 URL 分解为 Protocol、Host、Port、Path、Document 和 Params 等属性,开发者只需创建实例,调用 Parse 方法,然后读取 Host 属性即可。
代码实现细节:
在使用 TIdURI 时,建议将其封装在一个独立的函数中,传入一个 URL 字符串,函数内部负责创建 TIdURI 对象,进行解析,并返回 Host 属性,如果输入的 URL 格式严重错误,TIdURI 会抛出异常,因此调用端需要使用 try...except 进行捕获,这种方案代码简洁,可读性高,且自动遵循 RFC 3986 标准,是专业开发的首选。
替代方案:Windows 的 InternetCrackUrl API
如果不希望引入 Indy 库以减小程序体积,可以使用 Windows 的 WinINet 库中的 InternetCrackUrl 函数,这是一个底层的 C 风格 API,需要填充 URL_COMPONENTS 结构体,虽然功能强大,但代码繁琐,需要手动设置结构体中的指针和缓冲区大小,除非对体积有极致要求,否则在维护性和开发效率上,TIdURI 均优于 InternetCrackUrl。
专业解决方案与最佳实践
在实际的企业级项目中,建议构建一个专门的网络工具单元,将上述两种功能封装为静态类方法或单元函数。
错误处理与规范化

对于本地域名获取,如果计算机不在域环境中,GetComputerNameEx 可能会退而求其次返回单纯的计算机名,代码中应当能够识别这种状态,或者提供回退机制,对于 URL 解析,除了提取 Host,往往还需要规范化处理,去除域名前后的空格,统一转换为小写(虽然域名本身区分大小写,但通常为了比较方便而处理),或者处理 IDN(国际化域名,如中文域名)的 Punycode 转换。
性能考量
在需要高频解析的循环中(如遍历数万个 URL),反复创建和销毁 TIdURI 对象会产生一定的内存开销,可以考虑使用对象池技术,或者复用同一个 TIdURI 实例,仅改变其 URI 属性并重新解析,这种微小的优化在处理海量数据时能显著提升性能。
相关问答
Q1:在 Delphi 中,为什么获取本地域名时不推荐使用环境变量(如 COMPUTERNAME)?
A: 环境变量 COMPUTERNAME 仅包含 NetBIOS 名称(”SERVER01″),而不包含 DNS 后缀(”example.com”),在现代网络应用和 Web 开发中,通常需要完全限定域名(FQDN)来构建完整的 URI 或进行 Kerberos 身份验证,环境变量是在进程启动时快照的,如果在程序运行期间系统域名发生变化,环境变量不会自动更新,而 GetComputerNameEx API 则能获取实时数据,API 调用更具权威性和准确性。
Q2:使用 TIdURI 解析 URL 时,如何处理包含端口号的 Host 结果?
A: TIdURI 的设计非常严谨,它会将 Host 和 Port 分开存储,当解析 http://example.com:8080 时,TIdURI.Host 属性仅返回 example.com,而 TIdURI.Port 返回 8080,如果你希望得到的 Host 字符串包含端口号(即 example.com:8080),需要在代码中手动判断:TIdURI.Port 不为空且不是默认端口(如 80 或 443),则将 Host 和 Port 进行拼接,这种分离设计便于程序对端口进行单独的逻辑判断,是更专业的处理方式。
希望以上技术方案能为您的 Delphi 开发提供实质性的帮助,如果您在具体实施过程中遇到关于特定 Delphi 版本的兼容性问题,或者需要更高级的异步域名解析方案,欢迎在评论区留言,我们可以进一步探讨。


















