你在意過每天輸入的網址是否區分大小寫么?

letters.jpg

通常在瀏覽器地址欄輸入的網址我們叫做URL(統一資源定位符:Universal Resource Locators)。先來看一個簡單的URL:
http://www.example.com/here/is/path/file.html
這個URL可以簡單的描述為:使用HTTP協議去www.example.com所在的機器上讀取文件file.html這個文件。當然這是簡單的去理解,更詳細的解析可以看這里。從這個描述中可以看到,一個URL會被分成三部分,形如:[協議]://[域名]/[路徑]。

  • 協議:最常見的就是HTTP跟HTTPS,除了這個還有FTP文件傳輸協議等,這里是不區分大小寫的
  • 域名:域名(Domain Name)是需要通過域名系統(DNS)成功解析才能夠正常訪問到對應的IP地址,域名的命名規則之一就是:在域名中不區分大小寫
  • 路徑:路徑部分是否區分大小寫,則要看該網址對應的后臺是如何實現的

只有路徑部分才是會區分大小寫。每個網站都有后臺的服務器,如果服務器只是單純的采用路徑映射到機器的文件系統中,那不同的操作系統平臺是會有不同的區別的:

  • Linux:常見的是采用第三/四代擴展文件系統(ext3/4),在該文件系統下是需要區分大小寫的
  • Mac OS X: 使用的HFS / HFS + / APFS(2016年發布的macOS Sierra開始)文件系統是不區分大小寫
  • Windows:微軟公司開發的NTFS也是不區分大小寫的

對于我們最經常接觸到應用服務器來說,訪問一個路徑并不是指向文件系統中的某一個文件,而是作為一個字符串傳輸給應用服務器進行解析處理。

我這里用了Koa來做一個簡單的測試,在URL的路徑中輸入大小寫會出現什么情況。

const Koa = require('koa')
const app = new Koa()
const router = require('koa-router')()
router  
  .get('/', (ctx, next) => { ctx.body = `root path: ${ctx.req.url}`  })
  .get('/lowercase', (ctx, next) => {   ctx.body = `lowercase path: ${ctx.req.url}`  })
  .get('/UPPERCASE', (ctx, next) => { ctx.body = `uppercase path: ${ctx.req.url}` })
app.use(router.routes())
app.listen(3000)

??上面的六種情況可以我們可以看到,path并沒有區分大小寫。

當我在地址欄輸入:https://www.zhihu.com/EXPLORE 并沒有成功跳轉,而是出現了一個404頁面,這里又是什么原因呢?

我們還是以剛剛Koa的那個為例子來看。在例子中,使用了koa-router這個中間件來解析路由,koa-router里面有個match方法對path解析,而這個match方法主要是調用了path-to-regexp來生成進行解析,最終正則成功匹配對應的路由進行訪問相對應的資源。

下面看看沒有使用類似koa-router這樣的中間件,會是怎樣的效果。

app.use((ctx, next) => {
  const path = ctx.req.url
  if (path === '/lowercase') {
    ctx.body = 'success to request lowercase resource'
  } else if (path === '/UPPERCASE') {
    ctx.body = 'SUCCESS TO REQUEST UPPERCASE RESOURCE'
  } else {
    ctx.body = `success to visit: ${path}`
  }
})

可以看到如果自己對path進行處理的話,是可以自己控制是否大小寫敏感的。實際的運用中,為了易用性考慮,盡量滿足不區分大小寫,這應該也是router-koa這類中間件設計成case insensitive的考慮之一呱(猜的...hah)。知乎傳說用的是Python的Tornado,而Tornado的路由采用正則直接匹配解析的,所以,訪問https://www.zhihu.com/EXPLORE不成功應該是正則解析沒有做到大小寫不敏感吧(又是猜的...)

那在微博或者其他平臺里面經常看得到這樣的URL:http://t.cn/Ri98Hke 這是又是怎么一個情況呢?

這種一般叫做短鏈接,既然都叫短鏈接了,自然是希望越短越好啦,然而實際的操作中我們會發現,太短滿足不了日益增長的業務需求(然而并沒增長)吖,那太長了也不符合實際吖,我微博只給你發140個字符,你一個鏈接都40個字符了。所以,大小寫敏感的話會使得盡可能短又盡可能多這么變態的需求。以微博七位短鏈路徑為例,一起來看看(數字:10個,大寫字母:26個,小寫字母:26個)

  • case insensitive: (10 + 26)^7 = 78,364,164,096
  • case sensitive: (10 + 26 + 26)^7 = 3,521,614,606,208

所以短鏈還是大小寫敏感方便一些。

其實在早兩天遇到這個小問題之前我還是一直以為URL是嚴格區分大小寫的。我個人覺得如果api或者網頁提供給我們使用的時候,還是應該遵從api的命名規則去使用,盡管是大小寫不敏感。

源碼地址:CNBlackJ/caseSensitive
首發知乎專欄

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容