2011-06-30 5 views
9

Existe-t-il un meilleur moyen de convertir la localisation d'une URL en objet? Peut-être juste plus efficace ou réduit? J'utilise jQuery, mais JS pur peut aussi fonctionner.La requête window.location.search en tant que JSON

var query = window.location.search.substring(1), queryPairs = query.split('&'), queryJSON = {}; 
$.each(queryPairs, function() { queryJSON[this.split('=')[0]] = this.split('=')[1]; }); 

Répondre

21

Voici une pure fonction JS. Analyse la partie de recherche de l'URL actuelle et renvoie un objet. (Il est un peu bavard pour une meilleure lisibilité, l'esprit.)

function searchToObject() { 
    var pairs = window.location.search.substring(1).split("&"), 
    obj = {}, 
    pair, 
    i; 

    for (i in pairs) { 
    if (pairs[i] === "") continue; 

    pair = pairs[i].split("="); 
    obj[ decodeURIComponent(pair[0]) ] = decodeURIComponent(pair[1]); 
    } 

    return obj; 
} 

Sur le même sujet, vous n'êtes pas essayer de stocker les paramètres individuels dans « un JSON » mais dans « un objet ». ;)

+0

Merci, je corrige ma question. – thugsb

9

Si vous utilisez le navigateur moderne, ce produit le même résultat que la réponse acceptée:

function searchToObject(search) { 
    return search.substring(1).split("&").reduce(function(result, value) { 
    var parts = value.split('='); 
    if (parts[0]) result[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]); 
    return result; 
    }, {}) 
} 
1

Je voulais juste partager cette solution en utilisant un peu de ESNext et un réducteur.

Il fait à peu près la même chose que @Carlo, mais il est un peu plus propre si vous êtes à l'aise avec ES6 et réducteurs.

const urlSearchData = searchString => { 
    if (!searchString) return false; 

    return searchString 
     .substring(1) 
     .split('&') 
     .reduce((result, next) => { 
      let pair = next.split('='); 
      result[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]); 

      return result; 
     }, {}); 
}; 

const searchData = urlSearchData(window.location.search); 
1

Mon approche, simple et propre

var params = "?q=Hello World&c=Awesome"; 
 

 
params = "{\"" + 
 
     params 
 
     .replace(/\?/gi, "") 
 
     .replace(/\&/gi, "\",\"") 
 
     .replace(/\=/gi, "\":\"") + 
 
     "\"}"; 
 
    
 
params = JSON.parse(params); 
 

 
alert(decodeURIComponent(params.q)); 
 
alert(decodeURIComponent(params.c));

0

JSON Parse après stringify fait le travail de conversion en JSON avec les données du tableau.

?key1=val1&key2[]=val2.1&key2[]=val2.2&key2[]=val2.3&

{ 
    'key1' : 'val1', 
    'key2' : [ 'val2.1', 'val2.2', 'val2.3' ] 
} 

function QueryParamsToJSON() {    
 
    var list = location.search.slice(1).split('&'), 
 
     result = {}; 
 

 
    list.forEach(function(keyval) { 
 
     keyval = keyval.split('='); 
 
     var key = keyval[0]; 
 
     if (/\[[0-9]*\]/.test(key) === true) { 
 
      var pkey = key.split(/\[[0-9]*\]/)[0]; 
 
      if (typeof result[pkey] === 'undefined') { 
 
       result[pkey] = []; 
 
      } 
 
      result[pkey].push(decodeURIComponent(keyval[1] || '')); 
 
     } else { 
 
      result[key] = decodeURIComponent(keyval[1] || ''); 
 
     } 
 
    }); 
 

 
    return JSON.parse(JSON.stringify(result)); 
 
} 
 

 
var query_string = QueryParamsToJSON();

0

Remarque --Non doute au-dessus de solution fonctionne, mais il couvre wont tous les opérateurs

Devinez vous voulez quelque chose comme ça -

var search = location.search; 
var trimmedSearch = search.substring(1); 

var searchObj = trimmedSearch?JSON.parse(
    '{"' + trimmedSearch.replace(/&/g, '","').replace(/=/g,'":"') + '"}', 
    function(key, value) { 
     return key===""?value:decodeURIComponent(value) 
    } 
) 
: 
{} 

console.log(searchObj); 

ex -

Remplacer recherche @ 1ère ligne avec

search = "abc=foo&def=%5Basf%5D&xyz=5&foo=b%3Dar"; 

sortie que vous obtenez est

Object {abc: "foo", def: "[asf]", xyz: "5", foo: "b=ar"} 
0

bâtiment sur le travail ES6 de @ rafaelbiten, j'ajouté le support pour params qui ont pas de valeur et des tableaux de paramètres de requête du style d'entrée en double.

jsFiddle: https://jsfiddle.net/w922xefs/

const queryStringToJSObject = searchString => { 
    if (!searchString) return null; 

    return searchString 
    .replace(/^\?/, '') // Only trim off a single leading interrobang. 
    .split('&') 
    .reduce((result, next) => { 
     if (next === "") { 
     return result; 
     } 
     let pair = next.split('='); 
     let key = decodeURIComponent(pair[0]); 
     let value = typeof pair[1] !== "undefined" && decodeURIComponent(pair[1]) || undefined; 
     if (result.hasOwnProperty(key)) { // Check to see if this property has been met before. 
     if (Array.isArray(result[key])) { // Is it already an array? 
      result[key].push(value); 
     } 
     else { // Make it an array. 
      result[key] = [result[key], value]; 
     } 
     } 
     else { // First time seen, just add it. 
     result[key] = value; 
     } 

     return result; 
    }, {} 
); 
}; 

// Simple read of query string 
const searchData = queryStringToJSObject(window.location.search); 
0

Probablement la plus courte solution pour les cas simples:

location.search 
    .slice(1) 
    .split('&') 
    .map(p => p.split('=')) 
    .reduce((obj, [key, value]) => ({ ...obj, [key]: value }), {}); 
Questions connexes