js獲取地址欄URL上的參數

獲取地址欄上的URL參數現在最簡單通用的方法應該就是下面這種了。
function getUrlParam (name) {
    var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)');
    var r = window.location.search.substr(1).match(reg);
    if (r != null) return decodeURIComponent(r[2]); return null;
}
// 使用方法就是:http://www.test.com?a=123&b=231
var a = getUrlParam('a')            // a = 123
var b = getUrlParam('b')            // b = 231

不過這種方法是有缺陷的,它不能識別URL中值帶&或=,例如:http://www.test.com?a=1&23&b=231 在這裏我們
a參數定的值爲“1&23”,
如果還用上面的方法獲取的話:
a = 1
爲什麼呢,這就要解析一波這個方法的原理

// 首先是獲取URL
var r = window.location.search.substr(1);
// window.location.search.substr(1)可以獲取URL?後面的字符串例如:http://www.test.com?a=123&b=231得到的會是:a=123&b=231
// 然後再用正則獲取各個參數下的值
var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)')
// 1.這裏的(^|&)會匹配開頭爲空或&的字符
// 2.+ name + 這裏是匹配你要找的參數名
// 3.([^&]*)這裏是匹配“參數=”後面非&的字符
// 4.(&|$)這裏匹配以空或&結束的字符
// 這裏4個條件就把a=123&b=231裏的a=123&或&b=231找出來了
r = r.match(reg);
// 這裏match方法可以把符合正則的字符找出來,是以數組形式給出,例如我們要找的是a的話:
/*
    [
    'a=123&',                   // 這裏是整個正則匹配出來的
    '',                         // 這裏是(^|&)匹配出來的
    '123',                      // 這裏是([^&]*)匹配的
    '&'                         // 這裏是(&|$)匹配的
    ]
*/
// 我們需要的就是第三個([^&]*)匹配的字符
decodeURIComponent(r[2])            // 這裏拿到數組的第三個值再用decodeURIComponent轉碼

-就是如此要是再a=123&中提前遇到&就是提前終止。導致http://www.test.com?a=1&23&b=231 中a的值爲1

那要怎麼避免呢,這裏就要修改一下正則

var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)')
// 這裏前面的'(^|&)' + name + '='這段還是不變的。
// 不過([^&]*)這裏對&的限制要解除才行。不能讓它只匹配非&字符。所以改爲([.*])匹配任何字符(這樣說可能不是很嚴謹)
// (&|$)這裏的最後不能通過&或空判斷,應該是&xxx=這種結尾。所以改爲(&[^&=]+=|$)匹配,這裏的意思爲&開頭=結尾中間夾着非”&和=“的其他字符。這就滿足我們的要求了。
// 最終的正則表達式應該是:
var reg = new RegExp('(^|&)' + name + '=(.*)(&[^&=]+=)');
// 這裏因爲(.*)是匹配所有字符,所以會匹配到最後一個符合(&[^&=]+=)的參數停止,這就會有一個問題了,
// 例如"http://www.test.com?a=1&23&b=231&c=565" 這裏去‘a’的時候會取到'1&23&b=231',這裏包含了b的。所以這裏還要進一步處理只去&b=前面的值。
// 這裏假設取‘a’的值爲1&23&b=231
var a = '1&23&b=231'
var l = a.match(/&[^&=]+=/)[0]             // 這裏會得到第一個匹配‘/&[^&=]+=/’的字符串:'&b='
a = a.split(l)[0]                          // 這裏在根據l分割a,取第一個,就是我們要的了
// 不過這樣匹配不到最後一個參數,因爲最後一個是空結尾而不是"&xxx=",所以要寫多一個匹配最後一個參數的正則
var reg = new RegExp('(^|&)' + name + '=(.*)($)');

整個全新的方法是:

function getUrlParam (name) {
    var reg = new RegExp('(^|&)' + name + '=(.*)(&[^&=]+=)');
    var regLast = new RegExp('(^|&)' + name + '=(.*)($)');
    var r = window.location.search.substr(1).match(reg) || window.location.search.substr(1).match(regLast);
    if (r != null) {
      var l = r[2].match(/&[^&=]+=/)
      if (l) {
        return decodeURIComponent(r[2].split(l[0])[0]);
      } else return decodeURIComponent(r[2]);
    }
    return null;
}

有什麼錯誤請指出。。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章