URL帶有中文會引入哪些問題

處理含中文字符的 URL

1 為什么會出現“亂碼”或崩潰?

  • URL 標準(RFC 3986)規定:除少數保留字符外,URL 只能包含 ASCII。中文屬于 Unicode,因此必須先轉換。
  • 如果直接把 https://example.com/路徑/ 這樣的字符串傳給 URL(string:),Swift 會把它視為 非法,初始化直接返回 nil,后續網絡請求也會失敗。
  • 主機名部分(如 網址.中國)可以使用 IDN(Punycode)隱式轉換;路徑 / 查詢 / 片段 不會自動轉義,必須開發者處理。

2 Swift /Foundation 的行為細節

位置直接支持中文?需要開發者操作典型失敗表現
scheme / host?(自動轉 Punycode)
path / query / fragment?必須百分號編碼URL(string:) == nil
URLComponents / URLQueryItem?(自動做正確編碼)建議使用

絕對語句:未編碼的中文字符出現在路徑、查詢或片段里時,URL(string:) 一定 返回 nil,而不是“通常”。

3 安全構造 URL 的 3 個方法

// ? 方法 1:讓系統幫你轉義
let raw = "https://www.example.com/搜索?q=中文"
let encoded = raw.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
let url = URL(string: encoded)!   // 一定成功
// ? 方法 2:URLComponents 適合拼接 Query
var comps = URLComponents(string: "https://www.example.com/搜索")!
comps.queryItems = [URLQueryItem(name: "q", value: "中文")
]
let url = comps.url!              // 已正確編碼
// ? 方法 3:只編碼 path
let path = "路徑/子路徑".addingPercentEncoding(withAllowedCharacters: .urlPathAllowed)!
let url = URL(string: "https://example.com/\(path)")!
場景推薦字符集
path.urlPathAllowed
query key/value.urlQueryAllowed
fragment.urlFragmentAllowed

4 常見坑

  1. 雙重編碼

    • 調用兩次 addingPercentEncoding 會把 % 再轉義成 %25
    • 解決:只在“最終拼接”前調用一次,或依賴 URLComponents
  2. 手工拼接 Query

    • "q=\(value)" 如果 value& 會截斷。
    • URLQueryItem 永不過錯。
  3. 服務器端未解碼

    • 有些后端接口期望收到 UTF-8 原文:確認后端是否已自動 percentDecode
  4. UIWebView/WKWebView 打開中文 URL

    • 同樣先編碼,或使用 URLRequest(url:) 傳入已編碼的 URL

5 測試與調試

import XCTestfunc testChineseURL() {let comps = URLComponents(string: "https://域名.中國/搜索")!XCTAssertNotNil(comps.url)          // host 已轉 PunycodeXCTAssertEqual(comps.url!.absoluteString,"https://xn--ihq79i.xn--fiqs8s/%E6%90%9C%E7%B4%A2")
}
  • Xcode 網絡抓包:在 Console 或 Charles 中確認最終請求的 URL。
  • Unit Test:固化編碼邏輯,避免后期回歸。

6 總結

  • 中文主機名:Foundation 會自動 Punycode,無需關心。
  • 路徑 / 查詢 / 片段必須 百分號編碼,否則 Swift 一定失敗。
  • 最佳實踐URLComponents + URLQueryItem,讓系統幫你一次性處理所有細節。
  • 按照上面的套路,任何含中文字符的 URL 在 Swift 中都能被安全、穩定地使用。

by 侯仕奇?|?sqi.io

所以最簡單直接的方法就是嚴格規定:URL 中不允許使用中文 ?

可以,但你要知道這是「團隊約定」,不是網絡協議要求

做法優點明確缺點
硬性規定:所有接口只接受 ASCII(即先手動轉義)- 團隊心智負擔最低
- 服務器端解析簡單,不用擔心不同語言框架的容錯
- 可讀性差,日志里全是 %E6%B5%8B%E8%AF%95
- SEO / 分享鏈接體驗變差
- 第三方跳轉(微信、微博等)容易出現兩次轉義或未轉義問題
允許中文,但入口統一做一次 percent‐encode(推薦)- 代碼可讀(/搜索?q=中文
- 外部 copy-paste 時肉眼友好
- 仍然保證傳輸符合 RFC 3986
- 需要在 SDK 或 API Gateway 層加一段輕量工具方法
- 需要寫單元測試防止誤雙重轉義

為什么“完全禁用中文”并不總是最佳

  1. 現代瀏覽器與搜索引擎本來就支持 Unicode URL;直接禁用會犧牲人類可讀性。
  2. 移動端分享體驗:用戶復制的往往是裸中文 URL,如果后臺 400,用戶體驗會受損。
  3. 多語言產品:電商、文檔類站點需要保留自然語言 slug(/產品/蘋果手機)提升可維護性。

推薦落地方案

extension String {/// 將任何路徑或查詢中的非 ASCII 部分一次性安全轉義func urlEncodedPath() -> String {addingPercentEncoding(withAllowedCharacters: .urlPathAllowed)!}
}// ?? 統一在網絡層 (e.g. APIClient) 使用
func makeRequest(path: String, query: [String: String] = [:]) -> URLRequest {var comps = URLComponents()comps.scheme = "https"comps.host   = "example.com"comps.percentEncodedPath = path.urlEncodedPath()comps.queryItems = query.map { URLQueryItem(name: $0.key, value: $0.value) }return URLRequest(url: comps.url!)
}
  • 任何進入網絡層的字符串都可含中文
  • 網絡層保證 encode 一次且僅一次
  • 服務器端:若使用現代框架(Node/Go/Java/Spring)通常會自動解碼 %xx,無需額外處理。

結論:

  • 若團隊小、接口固定,強行禁止中文確實最省事,但長期會降低可維護性。
  • 更穩健的做法是允許中文輸入 → 統一轉義 → 所有鏈路都用合法 ASCII URL 傳輸
  • 不管選哪條路,關鍵在于「入口唯一化」:只讓一個地方負責轉義/解碼,就不會踩坑。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/86718.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/86718.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/86718.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

結構體字段能否單獨加 mut

你問的這個問題在 Rust 里很常見: 一、結構體字段能否單獨加 mut 1. 結構體字段能否單獨加 mut? 不能。Rust 中,mut 是用來修飾變量綁定的,可變性是綁定的屬性,而不是結構體字段本身的屬性。 你不能寫: …

scGPT-spatial 復現

文章目錄 ? 總體流程總覽(從 H5AD 到模型訓練)🔧 步驟 1:讀取 H5AD 文件并做基礎預處理🧱 步驟 2:構造訓練樣本輸入(token、value)📦 步驟 3:使用 DataColla…

運放電壓跟隨器為什么要加電阻

運放電壓跟隨器為什么要加電阻 我們常見運放的電壓跟隨器如下: 有時候會看見電路中加兩個電阻: 作用就是保護運放,起限流電阻的作用。 當輸入電壓高的時候,運放內部存在鉗位二極管,此電阻就能限流。 并不是所有運放…

MinerU 2.0部署

簡介 MinerU 2.0使用sglang加速,與之前差別較大,建議按照官方的Docker鏡像的方式啟動。 Docker鏡像 Dockerfile 這是官方的Dockerfile # Use the official sglang image FROM lmsysorg/sglang:v0.4.7-cu124# install mineru latest RUN python3 -m …

黑馬python(十七)

目錄: 1.數據可視化-地圖-基礎案例 2.全國疫情地圖 3.河南省疫情地圖繪制 4.基礎柱狀圖構建 5.基礎時間線柱狀圖繪制 6.動態GDP柱狀圖繪制 1.數據可視化-地圖-基礎案例 圖示有點對的不準,可以通過后面的參數 2.全國疫情地圖 3.河南省疫情地圖繪制…

Segment Anything in High Quality之SAM-HQ論文閱讀

摘要 最近的 Segment Anything Model(SAM)在擴展分割模型規模方面取得了重大突破,具備強大的零樣本能力和靈活的提示機制。盡管 SAM 在訓練時使用了 11 億個掩碼,其掩碼預測質量在許多情況下仍不理想,尤其是對于結構復雜的目標。我們提出了 HQ-SAM,使 SAM 能夠精確地分割…

深入理解_FreeRTOS的內部實現(2)

1.事件組 事件組結構體: 事件組 “不關中斷” 的核心邏輯 事件組操作時,優先選擇 “關調度器” 而非 “關中斷” ,原因和實現如下: 關調度器(而非關中斷) FreeRTOS 提供 taskENTER_CRITICAL()(…

【圖論題典】Swift 解 LeetCode 最小高度樹:中心剝離法詳解

文章目錄 摘要描述題解答案題解代碼分析思路來源:樹的“中心剝離法”構造鄰接表和度數組循環剝葉子終止條件 示例測試及結果時間復雜度空間復雜度總結 摘要 樹是一種重要的數據結構,在許多應用里,我們希望選一個根,讓這棵樹的高度…

Docker的介紹與安裝

? Docker 對初學者的簡單解釋和應用場景 1.什么是 Docker? 簡單來說,Docker 就像一個“裝箱子”的工具,這個箱子叫做“容器”。 你寫的程序和它運行需要的環境(比如操作系統、軟件、工具)都裝進一個箱子里。這個箱…

引導相機:工業自動化的智能之眼,賦能制造業高效升級

在工業自動化浪潮中,精準的視覺引導技術正成為生產效率躍升的關鍵。作為遷移科技——一家成立于2017年、專注于3D工業相機和3D視覺系統的領先供應商,我們深知"引導相機"的核心價值:它不僅是一個硬件設備,更是連接物理世…

智能相機如何重塑工業自動化?遷移科技3D視覺系統的場景革命

從硬件參數到產業價值,解碼高精度視覺系統的落地邏輯 一、工業視覺的“智慧之眼” 遷移科技深耕3D工業相機領域,以“穩定、易用、高回報”為核心理念,打造覆蓋硬件、算法、軟件的全棧式視覺系統。成立6年累計融資數億元的背后,是…

【數據挖掘】聚類算法學習—K-Means

K-Means K-Means是一種經典的無監督學習算法,用于將數據集劃分為K個簇(clusters),使得同一簇內的數據點相似度高,不同簇間的相似度低。它在數據挖掘、模式識別和機器學習中廣泛應用,如客戶細分、圖像壓縮和…

linux環境內存滿php-fpm

檢查 PHP-FPM 配置 pm.max_children:該參數控制 PHP-FPM 進程池中最大允許的子進程數。過高的子進程數會導致內存占用過大。你可以根據服務器的內存大小來調整 pm.start_servers:控制 PHP-FPM 啟動時創建的進程數。根據實際情況調整此值。 pm.min_spare_…

基于CNN卷積神經網絡圖像識別小程序9部合集

基于CNN卷積神經網絡圖像識別小程序合集-視頻介紹下自取 ? 內容包括: 基于python深度學習的水果或其他物體識別小程序 003基于python深度學習的水果或其他物體識別小程序_嗶哩嗶哩_bilibili 代碼使用的是python環境pytorch深度學習框架,代碼的環境安…

WebRTC(九):JitterBuffer

JitterBuffer Jitter “Jitter”指的是連續到達的媒體包之間時間間隔的變化。在網絡傳輸中,由于: 網絡擁塞路由路徑變化隊列排隊不同鏈路帶寬差異 導致包之間的接收時間不一致,這就是網絡“抖動”。 作用 **JitterBuffer(抖…

【推薦100個unity插件】在 Unity 中繪制 3D 常春藤,模擬生長——hedera插件的使用

注意:考慮到后續接觸的插件會越來越多,我將插件相關的內容單獨分開,并全部整合放在【推薦100個unity插件】專欄里,感興趣的小伙伴可以前往逐一查看學習。 效果演示 文章目錄 效果演示前言一、常春藤生成器工具下載二、工具使用1、…

【三維重建】【3DGS系列】【深度學習】3DGS的理論基礎知識之高斯橢球的幾何變換

【三維重建】【3DGS系列】【深度學習】3DGS的理論基礎知識之高斯橢球的幾何變換 文章目錄 【三維重建】【3DGS系列】【深度學習】3DGS的理論基礎知識之高斯橢球的幾何變換前言模型變換(Model Transformation)觀測變換(Viewing Transformation)視圖變換(View Transformation)投影…

EXISTS 和 NOT EXISTS 、IN (和 NOT IN)

在 SQL 中,EXISTS、NOT EXISTS 和 IN 都是用于子查詢的條件運算符,用于根據子查詢的結果過濾主查詢的行。它們之間的區別主要體現在工作方式、效率、對 NULL 值的處理以及適用場景上。 1. EXISTS 和 NOT EXISTS 作用: EXISTS: 檢查子查詢是…

GitHub 趨勢日報 (2025年06月25日)

📊 由 TrendForge 系統生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日報中的項目描述已自動翻譯為中文 📈 今日獲星趨勢圖 今日獲星趨勢圖 880 awesome 788 build-your-own-x 691 free-for-dev 427 best-of-ml-python 404 …

互聯網大廠Java求職面試:Java虛擬線程實戰

互聯網大廠Java求職面試:Java虛擬線程實戰 文章內容 開篇:技術總監與程序員鄭薪苦的三輪對話 在一場緊張而嚴肅的Java工程師面試中,技術總監張工正對候選人鄭薪苦進行深入提問。鄭薪苦雖然性格幽默,但對技術有著扎實的理解。今天…