首先看一下使用正則表達式獲取地址欄參數(shù)的方法
function GetQueryString(name)
{
var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)");
var r = window.location.search.substr(1).match(reg);
if(r!=null)return unescape(r[2]); return null;
}
這個函數(shù)是沒有問題的。但測試時發(fā)現(xiàn),對下面這個URL不能正確獲取參數(shù):
https://www.google.com.hk/?ion=1&espv=2#newwindow=1&safe=strict&q=regexp%E5%8F%AF%E5%8C%85%E5%90%AB%E5%A4%9A%E4%B8%AA
這個URL的參數(shù)應該有4個,分別是ion、espv、safe和q,但是我在chrome的console下輸入window.location.search得到的結(jié)果卻是

明顯少了兩個。百思不得其解。
糾錯
剛剛在segmentfault上找到了一些解釋,根據(jù)W3C的規(guī)定,在URL中fragment一定是在query之后的。(更詳細的可以看上一篇文章【地址欄參數(shù)詳解】)。
- query的規(guī)定是以第一個?開始,至行尾或#結(jié)束。
- fragment以#為開始,行尾為結(jié)束。
另外根據(jù)query和fragment字符限定的規(guī)定,兩者中都可以含有/和?,但不可以含有#。(還有其它的限制,這里是簡要的說法,因為我們此處要討論以?和#開頭的字串)
所以上面的URL中:
query就是?ion=1&espv=2;
fragment就是#newwindow=1&safe=strict&q=regexp%E5%8F%AF%E5%8C%85%E5%90%AB%E5%A4%9A%E4%B8%AA。
特殊情況
在使用Angular或者Vuejs構(gòu)建單頁應用時,我們可能會遇到這樣的URL:
http://localhost:8080/#!/account?id=123
根據(jù)前面的解釋,上面的URL以及Angular.js中出現(xiàn)的http://example.com/#/some/path?search=a#hash形式的URL實際上是不符合RFC規(guī)定的。
對URL在#之后的部分做變動不會刷新頁面,你可以在瀏覽器的console里分別輸入window.location.hash="#hash"和window.location.search="?sa"執(zhí)行看看結(jié)果,后者是會刷新頁面的。HTML5有History API可以不刷新頁面對URL進行修改,就不用加一個#號來防刷新了。但是此處是為了給不支持HTML5的瀏覽器提供兼容支持,也是無奈之舉。