web-dev-qa-db-fra.com

Existe-t-il une fonction native permettant de convertir JSON en paramètres d’URL?

J'ai besoin de convertir l'objet json en forme d'URL comme: "paramètre = 12 & asd = 1"

J'ai fait avec ça:

        var data = {
            'action':'actualiza_resultado',
            'postID': 1,
            'gl': 2,
            'gl2' : 3
        };

        var string_=JSON.stringify(data);

        string_=string_.replace(/{/g, "");
        string_=string_.replace(/}/g, "");
        string_=string_.replace(/:/g, "=")
        string_=string_.replace(/,/g, "&");
        string_=string_.replace(/"/g, "");

Mais je me demande s’il existe une fonction dans javascript ou dans un objet JSON pour le faire?

45
Felipe Morales

jQuery.param fait exactement cela. Si vous n'utilisez pas jquery, jetez un coup d'œil au source .

Si vous souhaitez vraiment réinventer les roues, voici ce qui se passe:

url = Object.keys(data).map(function(k) {
    return encodeURIComponent(k) + '=' + encodeURIComponent(data[k])
}).join('&')
99
georg

Utilisation de la syntaxe ES6: 

var data = {
  'action':'actualiza_resultado',
  'postID': 1,
  'gl': 2,
  'gl2' : 3
};

let urlParameters = Object.entries(data).map(e => e.join('=')).join('&');

console.log(urlParameters);

19
Tareq

Vous n'avez pas besoin de sérialiser ce littéral d'objet.

Une meilleure approche est quelque chose comme:

function getAsUriParameters(data) {
   var url = '';
   for (var prop in data) {
      url += encodeURIComponent(prop) + '=' + 
          encodeURIComponent(data[prop]) + '&';
   }
   return url.substring(0, url.length - 1)
}
getAsUriParameters(data); //"action=actualiza_resultado&postID=1&gl=2&gl2=3"
5
Minko Gechev

Mais je me demande s'il y a une fonction en javascript

Rien de pré-écrit dans le noyau.

ou json faire ça?

JSON est un format de données. Il n'a pas de fonctions du tout.


Il s’agit toutefois d’un problème relativement simple à résoudre, du moins pour les structures de données plates.

Ne codez pas les objets en JSON, alors:

function obj_to_query(obj) {
    var parts = [];
    for (var key in obj) {
        if (obj.hasOwnProperty(key)) {
            parts.Push(encodeURIComponent(key) + '=' + encodeURIComponent(obj[key]));
        }
    }
    return "?" + parts.join('&');
}

alert(obj_to_query({
    'action': 'actualiza_resultado',
    'postID': 1,
    'gl': 2,
    'gl2': 3
}));  

Il n’existe pas de méthode standard pour coder des structures de données complexes (par exemple, avec des objets ou des tableaux imbriqués). Il ne serait pas difficile d’étendre cela en émulant la méthode PHP (d’avoir des crochets dans les noms de champs) ou similaire.

4
Quentin

Comme @georg a dit, vous pouvez utiliser JQuery.param pour les objets plats.

Si vous devez traiter des objets complexes, vous pouvez utiliser JsonUri , un package python qui fait exactement cela. Il y a aussi une bibliothèque JavaScript

Disclaimer: Je suis l'auteur de JSONURI

3
Guilherme

Quelque chose que je trouve bien dans ES6:

function urlfy(obj) {
    return Object
        .keys(obj)
        .map(k => `${encodeURIComponent(k)} = ${encodeURIComponent(obj[k])}`)
        .join('&');
}
2
Cezar D.

Celui-ci traite les tableaux en modifiant le nameinto mutiple name[] 

function getAsUriParameters (data) {
  return Object.keys(data).map(function (k) {
    if (_.isArray(data[k])) {
      var keyE = encodeURIComponent(k + '[]');
      return data[k].map(function (subData) {
        return keyE + '=' + encodeURIComponent(subData);
      }).join('&');
    } else {
      return encodeURIComponent(k) + '=' + encodeURIComponent(data[k]);
    }
  }).join('&');
};
2
Perki

J'ai réalisé une implémentation prenant en charge des objets et des tableaux imbriqués, c'est-à-dire 

var data = {
    users: [
    {
      "name": "jeff",
      "tasks": [
        "Do one thing",
        "Do second thing"
      ]
    },
    {
      "name": "rick",
      "tasks": [
        "Never gonna give you up",
        "Never gonna let you down"
      ]
    }
  ]
}

Sera:

users[0][name]=jeff&users[0][tasks][0]=Do%20one%20thing&users[0][tasks][1]=Do%20second%20thing&users[1][name]=rick&users[1][tasks][0]=Never%20gonna%20give%20you%20up&users[1][tasks][1]=Never%20gonna%20let%20you%20down

Alors, voici l'implémentation:

var isObj = function(a) {
  if ((!!a) && (a.constructor === Object)) {
    return true;
  }
  return false;
};
var _st = function(z, g) {
  return "" + (g != "" ? "[" : "") + z + (g != "" ? "]" : "");
};
var fromObject = function(params, skipobjects, prefix) {
  if (skipobjects === void 0) {
    skipobjects = false;
  }
  if (prefix === void 0) {
    prefix = "";
  }
  var result = "";
  if (typeof(params) != "object") {
    return prefix + "=" + encodeURIComponent(params) + "&";
  }
  for (var param in params) {
    var c = "" + prefix + _st(param, prefix);
    if (isObj(params[param]) && !skipobjects) {
      result += fromObject(params[param], false, "" + c);
    } else if (Array.isArray(params[param]) && !skipobjects) {
      params[param].forEach(function(item, ind) {
        result += fromObject(item, false, c + "[" + ind + "]");
      });
    } else {
      result += c + "=" + encodeURIComponent(params[param]) + "&";
    }
  }
  return result;
};

var data = {
  users: [{
      "name": "jeff",
      "tasks": [
        "Do one thing",
        "Do second thing"
      ]
    },
    {
      "name": "rick",
      "tasks": [
        "Never gonna give you up",
        "Never gonna let you down"
      ]
    }
  ]
}

document.write(fromObject(data));

0
ishidex2

Le code personnalisé ci-dessus ne traite que des données à plat. Et JQuery n’est pas disponible en natif de réaction. Voici donc une solution js qui fonctionne avec des objets multi-niveaux et des tableaux en natif.

function formurlencoded(data) {
const opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};

let sorted = Boolean(opts.sorted),
    skipIndex = Boolean(opts.skipIndex),
    ignorenull = Boolean(opts.ignorenull),
    encode = function encode(value) {
        return String(value).replace(/(?:[\0-\x1F"-&\+-\}\x7F-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])/g, encodeURIComponent).replace(/ /g, '+').replace(/[!'()~\*]/g, function (ch) {
            return '%' + ch.charCodeAt().toString(16).slice(-2).toUpperCase();
        });
    },
    keys = function keys(obj) {
        const keyarr = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Object.keys(obj);
        return sorted ? keyarr.sort() : keyarr;
    },
    filterjoin = function filterjoin(arr) {
        return arr.filter(function (e) {
            return e;
        }).join('&');
    },
    objnest = function objnest(name, obj) {
        return filterjoin(keys(obj).map(function (key) {
            return nest(name + '[' + key + ']', obj[key]);
        }));
    },
    arrnest = function arrnest(name, arr) {
        return arr.length ? filterjoin(arr.map(function (elem, index) {
            return skipIndex ? nest(name + '[]', elem) : nest(name + '[' + index + ']', elem);
        })) : encode(name + '[]');
    },
    nest = function nest(name, value) {
        const type = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : typeof value === 'undefined' ? 'undefined' : typeof(value);
        let f = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;

        if (value === f) f = ignorenull ? f : encode(name) + '=' + f; else if (/string|number|boolean/.test(type)) f = encode(name) + '=' + encode(value); else if (Array.isArray(value)) f = arrnest(name, value); else if (type === 'object') f = objnest(name, value);

        return f;
    };

return data && filterjoin(keys(data).map(function (key) {
    return nest(key, data[key]);
}));

}

0
josh123a123

Basé sur la réponse de georg, mais en ajoutant aussi ? avant la chaîne et en utilisant ES6:

  const query = !params ? '': Object.keys(params).map((k, idx) => {
    let prefix = '';
    if (idx === 0) {
      prefix = '?';
    }
    return prefix + encodeURIComponent(k) + '=' + encodeURIComponent(params[k]);
  }).join('&');
0
dude