javascript
JS如何取得URL里的参数?
有一段時間沒寫過技術干貨文了,這兩天剛好遇到一個以前沒太在意的一個功能實現–前端獲取URL傳遞的參數
畢竟平時都是在后臺處理,掉了一堆頭發后,想想還是寫出來跟你們分享一下,以后要是你們遇到了也有個參考
要只是獲取一些常規字符串到沒什么難的,關鍵還有些亂七八糟的需求,什么同一個參數名傳遞了多次啊,傳數組啊。搞來搞去就寫了一大堆
先說說思路吧,如果你看這文章是想要解決問題,拿著代碼直接用的話,就直接看最后面的Code實現以及使用方法吧
用框架思維分析問題
給你一個如下的URL:
http://NaoNao.com/?product=shirt&color=blue&newuser&size=m#Hello
將URL里傳遞的參數轉換為object對象,這樣我們在使用參數的時候也更為方便
我曾多次強調框架思維,現在遇到這個問題了,我們就拿框架思維來分析一下,該怎樣才能快速解決
首先是要了解我們的目的是什么?目的很簡單,取得URL內傳遞的參數,并且解析成對象
接著再分析我們現在知道些什么?有一串URL
我們再來分析,如果從URL中獲得傳遞的參數,也就是為了達到目的,我們該做些什么?
URL的特征我們大致都知道,就是第一個?后面的字符串,都是傳遞的參數,但是有個特殊情況請不要忘記了,URL后面有時候會帶上一個#,而#后面的內容,并不是我們要傳遞的參數,而是網頁位置的標識符
如果URL中包含了#,我們只需要解析?到#之間的字符串就可以了,如果不包含,那么第一個?后所有的內容都是我們需要解析的
你可能覺得我是在說廢話,這么明顯的事情,只要不是白癡都能看得懂
我當然知道,只要不是白癡都能看得懂,但我為什么要強調呢?因為我們想要快速的解決問題,必須具備框架思維,也可以說是工程思維
你可能有會說,這么簡單的問題需要這樣分析么?我們一看就知道了,鬧鬧你這是殺雞用牛刀
雖說是殺雞用牛刀,可要想培養自己的工程思維,那么必須保持刻意訓練,直到隨手拈來
好了,分析完后,我們按照上面的思路來逐步實現,實現的時候可能會遇到其它的問題,到時候再分析,再解決
畢竟再牛逼的工程師,也不會在動手前就想的面面俱到,只能是在動手實現前盡可能的考慮周到,遇到問題時再快速的迭代更新
JS獲取URL參數的過程
先用JS拿到URL,如果函數傳參了URL,那就用參數。如果沒傳參,就使用當前頁面的URL
var queryString = url ? url.split('?')[1] : window.location.search.slice(1);如果后面的字符串存在#,我們還得將#后面的字符串去掉,因為#后面的內容并不是我們需要獲取的參數,而是網頁位置的標識符
queryString = queryString.split('#')[0];好了,把干擾的部分都移除后,我們可以開始安心的解析參數了,先將傳遞的參數分成數組
var arr = queryString.split('&');現在我們可以獲得一個字符串數組
['product=shirt', 'color=blue', 'newuser', 'size=m']將字符串拆分成數組后,我們通過創建一個對象,用來存儲我們所有的參數
var obj = {};我們可以通過遍歷數組arr,將它拆分成鍵值對。把這個字符串做成key:value的對象
var a = arr[i].split('=');接下來就是要為每一個變量key分配對應的值value,如果我們得到的value不是一個正確的參數,我們就用true來表示這個參數名存在,當然了,你也可以根據自己的實際情況來做改變
var paramName = a[0]; var paramValue = typeof(a[1]) === 'undefined' ? true : a[1];在這里我只是對undefined做了標記,如果是NaN,我是直接拿它當字符串處理了
在這里有一個小坑得提醒一下,我們在調用函數,獲取對象取值的時候,如果URL傳遞的key為大寫,我們取對象時寫的小寫,那么結果就是為undefined
比如URL為http://NaoNao.com/?NamE=NaoNao,如果不做大小寫的處理,調用對象取值時getAllUrlParams().NamE才能取到值NaoNao,如果做了處理,我們使用時只需要全部寫成小寫/大寫即可,例如getAllUrlParams().name
我在這就全部轉為小寫了,如果你對大小寫要求區分,那到時候把這段Code給去掉就好了
paramName = paramName.toLowerCase(); if (typeof paramValue === 'string') paramValue = paramValue.toLowerCase();接下來我們就要去處理我們接受到的paramValue,這些參數可能是索引數組,非索引數組,又或者是常規字符串
如果是索引數組,我們需要將paramValue轉換成數組,并且將索引對應的值,放入索引對應的位置
如果是非索引數組,我們就要將paramValue放到數組中
如果只是常規的字符串,我們就需要為我們的對象obj創建一個常規的屬性,并為其分配值。
如果這個key已經存在,那么我們就要將現有的paramValue從key:value轉換為數組,并將它放到數組中
拿幾個實際案例,感受一下我們要做什么吧
// 索引數組 getAllUrlParams('http://NaoNao.com/?colors[0]=red&colors[2]=green&colors[6]=blue'); // { "colors": [ "red", null, "green", null, null, null, "blue" ] }// 非索引數組 getAllUrlParams('http://NaoNao.com/?colors[]=red&colors[]=green&colors[]=blue'); // { "colors": [ "red", "green", "blue" ] }// 多次傳遞同一個key getAllUrlParams('http://NaoNao.com/?colors=red&colors=green&colors=blue'); // { "colors": [ "red", "green", "blue" ] }// 傳遞了key,但是沒傳value getAllUrlParams('http://NaoNao.com/?product=shirt&color=blue&newuser&size=m'); // { "product": "shirt", "color": "blue", "newuser": true, "size": "m" }我做這寫判斷時用的是正則表達式,在這里就不解釋正則了。。。畢竟解釋起來篇幅就太長了,能看懂就盡量看吧
每個正則要解析什么,在注釋中都寫了例子,稍微了解點正則表達式的同學,多半也能看懂的
對應的代碼實現如下:
// 如果paramName以方括號結束, e.g. colors[] or colors[2] if (paramName.match(/\[(\d+)?\]$/)) {// 如果paramName不存在,則創建keyvar key = paramName.replace(/\[(\d+)?\]/, '');if (!obj[key]) obj[key] = [];// 如果是索引數組 e.g. colors[2]if (paramName.match(/\[\d+\]$/)) {// 獲取索引值并在對應的位置添加值var index = /\[(\d+)\]/.exec(paramName)[1];obj[key][index] = paramValue;} else {// 如果是其它的類型,也放到數組中obj[key].push(paramValue);} } else {// 處理字符串類型if (!obj[paramName]) {// 如果如果paramName不存在,則創建對象的屬性obj[paramName] = paramValue;} else if (obj[paramName] && typeof obj[paramName] === 'string') {// 如果屬性存在,并且是個字符串,那么就轉換為數組obj[paramName] = [obj[paramName]];obj[paramName].push(paramValue);} else {// 如果是其它的類型,還是往數組里丟obj[paramName].push(paramValue);} }如果你的URL的傳參包含了一些特殊字符,比如空格。例如url="NaoNao.com/?name=Nao%20Nao",拿到對象值之后,是需要解碼后才能獲得正確的值的
var original = getAllUrlParams().name; // 'Nao%20Nao' var decode = decodeURIComponent(original); // 'Nao Nao'具體實現以及使用方式
下面是JS的具體的完整實現,你們復制回去就可以用
function getAllUrlParams(url) {// 用JS拿到URL,如果函數接收了URL,那就用函數的參數。如果沒傳參,就使用當前頁面的URLvar queryString = url ? url.split('?')[1] : window.location.search.slice(1);// 用來存儲我們所有的參數var obj = {};// 如果沒有傳參,返回一個空對象if (!queryString) {return obj;}// stuff after # is not part of query string, so get rid of itqueryString = queryString.split('#')[0];// 將參數分成數組var arr = queryString.split('&');for (var i = 0; i < arr.length; i++) {// 分離成key:value的形式var a = arr[i].split('=');// 將undefined標記為truevar paramName = a[0];var paramValue = typeof (a[1]) === 'undefined' ? true : a[1];// 如果調用對象時要求大小寫區分,可刪除這兩行代碼paramName = paramName.toLowerCase();if (typeof paramValue === 'string') paramValue = paramValue.toLowerCase();// 如果paramName以方括號結束, e.g. colors[] or colors[2]if (paramName.match(/\[(\d+)?\]$/)) {// 如果paramName不存在,則創建keyvar key = paramName.replace(/\[(\d+)?\]/, '');if (!obj[key]) obj[key] = [];// 如果是索引數組 e.g. colors[2]if (paramName.match(/\[\d+\]$/)) {// 獲取索引值并在對應的位置添加值var index = /\[(\d+)\]/.exec(paramName)[1];obj[key][index] = paramValue;} else {// 如果是其它的類型,也放到數組中obj[key].push(paramValue);}} else {// 處理字符串類型if (!obj[paramName]) {// 如果如果paramName不存在,則創建對象的屬性obj[paramName] = paramValue;} else if (obj[paramName] && typeof obj[paramName] === 'string') {// 如果屬性存在,并且是個字符串,那么就轉換為數組obj[paramName] = [obj[paramName]];obj[paramName].push(paramValue);} else {// 如果是其它的類型,還是往數組里丟obj[paramName].push(paramValue);}}}return obj; }這個函數該怎么使用呢?
直接把URL參數當成對象調用就OK咯~
以文章開篇的URL為例子
// http://NaoNao.com/?product=shirt&color=blue&newuser&size=m#HellogetAllUrlParams().product; // 'shirt' getAllUrlParams().color; // 'blue' getAllUrlParams().newuser; // true getAllUrlParams().NB; // undefined getAllUrlParams('http://NaoNao.com/?NaoNao=shuai').NaoNao; // shuai不兼容IE的解決方案
如果我們不需要考慮IE這種妖嬈賤貨,以及一些非常老版本瀏覽器,就用瀏覽器內URLSearchParams的接口吧。。。這個接口可以直接拿取URL內的參數
// URL is http://NaoNao.com/?product=shirt&color=blue&newuser&size=m const urlParams = new URLSearchParams(window.location.search); // 判斷參數是否存在 console.log(urlParams.has('product')); // true // 獲取參數對應的值 console.log(urlParams.get('product')); // "shirt"這個接口還提供了更多成熟的方法,比如keys(),Values(),還有entries(),這個接口該怎么使用,直接去看官方文檔就好了,用起來還是很虛浮的
微信掃碼關注公眾號「鬧鬧吃魚」,每周都有好分享,還可領取學習資源哦~不僅僅只是技術!
總結
以上是生活随笔為你收集整理的JS如何取得URL里的参数?的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 揭秘:QQ号码能准确测出QQ主人年龄问题
- 下一篇: mysql docker还是rds_rd
