爲何中文名稱的圖片打開後網址是一串亂碼?爲何好好的短網址複製粘貼就變長了一大長串?罪魁禍首竟然是……html
杭州終於出梅了!二狗子看到氣象臺發佈的消息,開心的不得了。杭州的雨從五月底一直下,天天除了雨仍是雨,天空都是灰濛濛的,都快把人搞抑鬱了。出梅了,天晴了,二狗子的心也隨着藍天上的白雲飄蕩出去了。編程
同事小峯峯告訴二狗子,公司後邊的皇后公園,向日葵開的正好,一大片一大片的綿延出去,陽光下金燦燦的,可好看了。「要不要一塊兒去看看?你拍點照片給婷婷唄~」瀏覽器
二狗子一想起女神婷婷很喜歡向日葵,拍點美麗的照片,能看到婷婷甜甜的笑,就火燒眉毛地拉着小峯峯往公園跑。安全
二狗子拍了好多照片,精挑細選了好幾張,上傳到本身的圖片網站了。他用瀏覽器打開圖片看了看,沒有問題,很是完美,就複製了圖片地址發給婷婷。服務器
二狗子有點尷尬,明明在瀏覽器中是正常顯示的 URL 地址,怎麼複製出來就變成一堆奇怪的字符了呢?網絡
二狗子百思不得其解,得,仍是問一下本身的存儲服務商——無所不能的又拍雲吧。app
客服喬巴接待了二狗子,並告訴了二狗子這個問題的由來。編程語言
經過互聯網來訪問網絡中資源的時候,最多見就是經過瀏覽器輸入資源的 URL 地址來進行訪問。網站
URL(Uniform Resource Locator),是互聯網中的一個核心概念,官方名稱叫作統一資源定位符。簡單的來講,URL 就是一個由網站開發者給資源在互聯網上分配的地址。通常來講,每一個有效的 URL 都指向單獨的一個資源,這個資源能夠是HTML 頁面、CSS 文檔,又或者是一幅圖像等。編碼
一個 URL 由不一樣的部分組成,其中一些是必須的,而另外一些是可選的。下面咱們來看下 URL 的具體組成部分:
上圖就是完整的 URL 結構展現。不少時候其中的一些部分是用不到的,例如 user information。做爲參考,咱們能夠來看一下又拍雲存儲的 URL 地址。
https://www.upyun.com/product...
通常常見的 URL 地址由這三個部分組成,其他的部分根據開發的須要,能夠進行自定義。
瞭解 URL 的概念後,就知道二狗子的圖片連接 http://fileupload-upyun.test.... 的由來了。經過這個地址,婷婷能夠訪問到二狗子服務器上拍攝的向日葵圖片。可是,爲何二狗子複製了瀏覽器地址欄中的地址,發送給婷婷的時候,URL 卻變成了 http://fileupload-upyun.test.... 了呢?
咱們能夠看到,二狗子發給婷婷的連接,改變了的部分屬於 URL 的 path 部分,並且,英文部分其實沒有改動,只有中文的部分被轉成 %XX 的這種編碼格式了。
雖然,這不會影響圖片的打開,地址依舊是有效的。可是爲何瀏覽器要把中文轉換成這種奇怪的形式呢?
咱們先來看一個例子。若是訪問下面這個 URL 連接:
https://www.baidu.com/s?wd=?#!
這是使用百度進行搜索的一個連接,/s 後面跟着的 ? 表明請求參數(query),也就是咱們想向請求的服務器提交一些參數。wd 爲百度規定的查詢參數名,wd 後邊跟着的就是須要搜索的內容。
咱們想搜索 ?#! 這個內容,但是當你複製這個連接放在瀏覽器中打開時,會發現一個問題,百度僅僅是搜索了 ? 這個內容,#! 不見了。
爲何呢?若是你仔細看上面那張 URL 的構成圖,會發現 URL 結構中還有一個錨點(fragment)的部分,分隔符號就是 #。
因此這裏就會出現一個問題,咱們的業務需求是將 # 當作一個普通文原本進行搜索,可是 # 在 URL 中有特定的意思,因此瀏覽器就遇到了一個解釋歧義的問題。
這就引伸出一個問題,URL 在數據傳遞中,若是存在用做分隔符等特殊做用的保留字符怎麼辦?
在實際的業務場景中,會常常碰到一些在 URL 中有歧義性的數據,爲了不解釋錯誤,開發者想出了一個解決方法,就是對這些數據進行必定的處理,從而解決歧義的問題。處理的方法有不少種,最經常使用的處理方式,就是對歧義性的數據進行 URL 百分號編碼。
哪些是會引發歧義的數據呢?
根據 RFC 3986(https://tools.ietf.org/html/r...)的規定,咱們能夠獲得下面的結果。
保留字符由組件分隔符(gen-delims)和子組件分隔符(sub-delims)組成,這些字符在 URL 中都有特殊的意義:
Reserved = gen-delims / sub-delims
URL 中能夠直接使用的非保留字符則有:
Unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
這下子咱們就瞭解了,爲何 URL 中有時會出現奇怪的字符,不少時候瀏覽器會自動幫咱們作編碼和解碼的操做。就像「向日葵」的 URL 同樣,中文部分由於並不在 ASCII 碼中,因而瀏覽器進行 URL 百分號編碼的形式來進行訪問。
(又拍雲服務名的合法範圍就是在非保留字符中獲取,而不能指定爲任意字符)
最多見的編碼形式就是百分號編碼(pct-encoded),這也是瀏覽器默認的編碼形式。
pct-encoded = "%" HEXDIG HEXDIG
百分號編碼一個保留字符, 首先須要把該字符的 ASCII 的值表示爲兩個 16 進制的值, 而後在其前面放置轉義字符(%)。對於非 ASCII 字符, 則須要轉換爲 UTF-8 字節序, 而後每一個字節按照上述方式表示。
(感興趣的同窗能夠參考百分號編碼 https://zh.wikipedia.org/zh-h... 條目)
各個編程語言中也有相對應的方法能夠進行百分號編碼,例如 JavaScript 中就提供了多種編碼方法,經常使用的有 encodeURI 和 encodeURIComponent 兩個方法。
喬巴說,在平常開發使用中,咱們使用的開發庫對 URL 編碼的判斷標準可能並不相同,這是由於這些庫所面臨的網絡環境中,對於特殊字符的安全處理策略各有判斷,這也會致使 URL 中若是存在一些特殊字符,開發、訪問過程當中可能就會出現一些奇怪的問題。在這裏也建議你們使用非保留字符來設計本身程序中 URL 部分,避免一些沒必要要的 BUG 產生。
聽完喬巴的介紹,二狗子終於明白了爲啥 URL 中出現這些奇怪的字符了。嘿嘿,這下能夠和婷婷解釋 URL 爲何這麼長咯。