You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift处理国际化域名(IDN)时URL返回nil及网络请求证书报错问题

解决方法

第一个问题:URL构造失败

URL(string:)要求输入的字符串必须是符合RFC 2396规范的编码后字符串,直接拼接Unicode格式的IDN域名会因为包含非ASCII字符无法完成校验,导致构造失败。
你采用的URLComponents分别配置scheme和host的方案是正确的,URLComponents的host属性原生支持IDN的自动编码,可以解决构造失败的问题。

第二个问题:URLSession请求报证书无效错误

这个报错属于误导性提示,根因是URLSession进行TLS证书的域名校验时,不会自动将Unicode格式的U-Label转换为punycode格式的A-Label,而站点证书绑定的是IDN对应的punycode域名,二者匹配失败才触发了证书无效的错误。

你可以提前手动将U-Label转换为punycode格式再使用,以下是完整的可运行代码:

import Foundation

extension String {
    /// 将国际化域名的U-Label转换为punycode格式的A-Label
    var idnToPunycode: String? {
        let cfString = NSMutableString(string: self) as CFMutableString
        // 执行IDN到ASCII的punycode转换
        guard CFStringTransform(cfString, nil, kCFStringTransformToASCII, false) else {
            return nil
        }
        return cfString as String
    }
}

let uLabel = "համընդհանուր-ընկալում-թեստ.հայ"
guard let punycodeHost = uLabel.idnToPunycode else { exit(1) }

var comps = URLComponents()
comps.scheme = "https"
comps.host = punycodeHost
guard let url = comps.url else { exit(1) }

let task = URLSession.shared.dataTask(with: url) { data, response, error in
    guard let rawContent = data, 
          let content = String(data: rawContent, encoding: .utf8),
          content.contains("UASG Testbed Landing Page") else {
        exit(1)
    }
    exit(0)
}
task.resume()
RunLoop.main.run()

内容的提问来源于stack exchange,提问作者Guillaume Blanchet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 00:36:00