從QQ密碼修改的小問題回顧下URL Fragment


上個星期天晚上約11點半,左耳朵耗子在新浪微博上吐槽QQ安全中心密碼修改的問題,引來不少圍觀。QQ安全中心的兄弟收到用戶反饋后,第一時間fix bug並發布,其高效着實令人佩服。

當時也圍觀了下,問題並不復雜,是由於業務代碼對於url的不恰當處理導致的(詳見本文第3點),涉及url fragment(#)的內容,於是順便重溫了下這塊的內容。

文章主要參考了httpwatch博客的一篇文章:《6 Things You Should Know About Fragment URLs》

其中1-5點的內容比較基礎,6-7點的內容對於ajax應用的開發有不錯的指導意義,可以了解下。

1、#右邊的字符,代表了一個頁面的特定位置

比如下面的url

 http://www.example.com/index.html#casper

瀏覽器會尋找頁面里面,name屬性跟casper匹配的a標簽,並自動滾動定位到該位置,如下

<a name="casper">頁面會自動滾動到這個標簽所在的位置</a>

 

2、HTTP請求里,不會帶上#后面的部分

在地址欄里輸入http://www.cnblogs.com/#casper,打開調試工具查看網絡請求,會發現#casper並沒有出現再網絡請求中,如圖所示

 

3、#后面的所有字符,都會被瀏覽當作位置標識符

關於這點,不少新手,包括老手,一不小心就掉坑里了。舉個最新的例子,前不就做耳朵耗子在微博上吐槽騰訊安全中心密碼修改的問題,如圖

果斷測試並抓了下包,一下就發現問題了:#后面的字符被截斷了,於是便得到了錯誤的校驗提示

https://aq.qq.com/cn2/ajax/get_psw_sgn?psw=Ae#ba234aaafff

 

4、改變#不會導致頁面重新加載,但是會改變瀏覽器歷史記錄

關於這點很容易測試,假設當前訪問的頁面是http://www.qq.com,打開控制台,分別輸入如下命令看下區別(是否刷新),然后,再查看window.history有什么區別(歷史記錄是否變化)

location.href += '#caper';  //頁面不會刷新
location.href += '?visitor=caper';  //頁面刷新

在普通的網頁瀏覽中,我們每點擊一個網頁鏈接,就會在瀏覽器歷史記錄中新增一條瀏覽記錄,並通過瀏覽器的導航功能輕松進行'上一步'、'下一步'的操作。

但對於ajax應用,url通常是不會變化的,尤其是單頁面應用。這也就意味着,用戶習以為常的瀏覽器導航功能(上一步、下一步)失去了作用,這在體驗上是比較糟糕的。通過#,開發者可以利用不同的id,標識當前頁面所處狀態,提升用戶體驗。

 

5、JS中可以通過window.location.hash來讀取或改變#的值

沒什么好講的,可結上一點簡單測試下 :)

 

6、谷歌的網絡蜘蛛默認會忽略#后面的內容

谷歌網絡蜘蛛負責爬取網頁的內容,以及網頁里面的鏈接,它們會成為google搜索索引的一部分。網絡蜘蛛會抓取並分析HTML,但由於它並不是瀏覽器程序,也沒有javascript引擎,頁面上用來加載顯示內容的javascript並不會被執行。因此,#后面的字符會被網絡蜘蛛忽視,只抓取#前面的內容,舉例:

鏈接一:http://www.cnblogs.com/#casper
鏈接二:http://www.cnblogs.com/#chyingp

對於網絡蜘蛛來說,鏈接一、鏈接二其實是一樣的,它只會抓取http://www.cnblogs.com的內容,盡管兩個鏈接可能展示的是不同的內容

這點無論對於開發者,還是搜索引擎都是不利的,前者辛苦創作的內容(應用)少了很多被訪問的機會,而后者則失去了進一步豐富其內容索引的機會,特別是在ajax應用越來越多的今天。

為了解決這個問題,google提供了一個解決方案:hash bang,只要將#改成#!即可,實現大致為:當網絡蜘蛛遇到#!時候,會自動將#!identifier轉成_escaped_fragment_=identifier形式的參數,修改下之前的鏈接

鏈接一(新):http://www.cnblogs.com/#!casper
鏈接二(新):http://www.cnblogs.com/#!chyingp

在網絡蜘蛛眼里,上面的鏈接是這樣的

鏈接一(轉化后):http://www.cnblogs.com/?_escaped_fragment_=casper
鏈接二(轉化后):http://www.cnblogs.com/?_escaped_fragment_=chyingp

這里有兩個注意點:

  1. 將#改成!#告訴網絡蜘蛛:我們支持這個解決方案:hash bang
  2. 相應的,我們的應用也需要具備相應的支持能力,對於網絡蜘蛛帶escaped_fragment=casper的GET請求,需要能夠提供相應的網頁內容

更多內容,請參考:http://support.google.com/webmasters/bin/answer.py?hl=en&answer=174992

 

7、補充內容:hash bang的應用(注意這里的例子有些誤導)

看了網上不少這方面的內容,都是以twitter為例子,但由於中國的特殊國情,訪問twitter略麻煩,於是舉個離我們比較近的例子:QQ空間。

應該很多人都有在用QQ空間,打開QQ空間,並點擊“日志”,觀察下當前的url

http://user.qzone.qq.com/替換成自己的QQ號碼/infocenter#!app=2&via=QZ.HashRefresh&pos=catalog_list

可以發現,infocenter后面用的是#!,按照之前的講解,我們稍稍做下修改,回車訪問,證實我們的猜想。

http://user.qzone.qq.com/替換成自己的QQ號碼/infocenter?_escaped_fragment_=app=2&via=QZ.HashRefresh&pos=catalog_list

 

2013/04/02添加

重新測試了下,空間目前不支持_escaped_fragment_,因此即使加了這個參數,也是會定位到個人中心

1、空間加#!的原因
    1)緩存考慮
    2)為可能的索引優化做准備

2、沒支持_escaped_fragment_的原因:

    非技術實現上的困難,因為目前的產品性質對於這塊優化的需求不大

這塊的例子,據說twitter是做了的,但得翻牆才能測試,先TODO一下。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM