76

我需要将 json 对象转换为 url 形式,例如:“parameter=12&asd=1”

我完成了这个:

        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, "");

但我想知道javascript或JSON对象中是否有任何函数可以做到这一点?

4

13 回答 13

173

jQuery 提供param的正是这样做的。如果您不使用 jquery,请查看源代码

基本上,它是这样的:

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

2019 年更新URLSearchParams:现在有一个用于此类事物的内置对象:

let myParams = {'foo': 'hi there', 'bar': '???'};

let u = new URLSearchParams(myParams).toString();

console.log(u);

于 2013-01-25T15:53:10.137 回答
26

使用 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);

于 2016-10-27T14:54:03.573 回答
10

我做了一个支持嵌套对象和数组的实现,即

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"
      ]
    }
  ]
}

将会:

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

所以,这里是实现:

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));

于 2019-03-02T13:09:56.580 回答
6

您不需要序列化此对象文字。

更好的方法是这样的:

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"
于 2013-01-25T15:49:18.080 回答
6

我发现在 ES6 中看起来很漂亮的东西:

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

稍后更新(同样的事情,也许更干净一些):

const urlfy = obj => Object
    .keys(obj)
    .map(k => encodeURIComponent(k) + '=' + encodeURIComponent(obj[k]))
    .join('&');
于 2018-03-01T16:29:12.987 回答
5

就像@georg 所说,您可以将JQuery.param用于平面对象。

如果您需要处理复杂的对象,您可以使用JsonUri,这是一个执行此操作的 python 包。它也有 JavaScript 库

免责声明:我是 JSONURI 的作者

编辑:我后来了解到,您也可以只对您的有效负载进行 base64 编码 - 大多数语言都支持 base64 编码/解码

例子

x = {name: 'Petter', age: 47, places: ['Mozambique', 'Zimbabwe']}
stringRep = JSON.stringify(x)
encoded = window.btoa(stringRep)

给你eyJuYW1lIjoiUGV0dGVyIiwiYWdlIjo0NywicGxhY2VzIjpbIk1vemFtYmlxdWUiLCJaaW1iYWJ3ZSJdfQ==,你可以用它作为一个uri参数

decoded = window.atob(encoded)
originalX = JSON.parse(decoded)

不用说,它有自己的警告

于 2014-11-14T03:16:36.740 回答
4

但我想知道javascript中是否有任何功能

核心中没有预先写好的东西。

或json来做到这一点?

JSON 是一种数据格式。它根本没有功能。


这是一个相对微不足道的问题,至少对于平面数据结构来说是这样。

不要将对象编码为 JSON,然后:

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
}));  

没有标准的方法来编码复杂的数据结构(例如嵌套对象或数组)。扩展它以模拟 PHP 方法(在字段名称中使用方括号)或类似方法并不难。

于 2013-01-25T15:51:41.720 回答
3

这一个通过将数组更改为多个来处理name数组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('&');
};
于 2013-09-06T15:14:37.393 回答
2

Vanilla JavaScript 的最佳解决方案:

var params = Object.keys(data)
  .filter(function (key) {
    return data[key] ? true : false
  })
  .map(function (key) {
    return encodeURIComponent(key) + '=' + encodeURIComponent(data[key])
  })
  .join('&');

PS:这里使用过滤器来去除空或未定义的参数。它使网址看起来更干净。

于 2020-01-13T21:36:42.163 回答
0

上面的自定义代码只处理平面数据。并且 JQuery 在本机反应中不可用。所以这里有一个 js 解决方案,它可以在 react native 中处理多级对象和数组。

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]);
}));

}

于 2018-08-02T17:58:01.977 回答
0

Make a utility if you have nodejs

const querystring = require('querystring')

export function makeQueryString(params): string {
  return querystring.stringify(params)
}

import example

import { makeQueryString } from '~/utils'

example of use

  makeQueryString({
    ...query,
    page
  })
于 2021-03-16T09:01:06.770 回答
0

基于georg的回答,但也在?字符串之前添加并使用ES6:

  const query = !params ? '': Object.keys(params).map((k, idx) => {
    let prefix = '';
    if (idx === 0) {
      prefix = '?';
    }
    return prefix + encodeURIComponent(k) + '=' + encodeURIComponent(params[k]);
  }).join('&');
于 2018-02-13T22:23:28.060 回答
0

由于大多数答案仅将平面对象转换为查询参数,我想分享一下我的。

这个函数可以处理平面对象,以及嵌套数组/对象,同时只使用普通 JS。

        function incapsulateInBrackets(key)
        {
            return '[' + key + ']';
        }

        function encode(object, isSubEncode=false, prefix = '')
        {
            let parts = Object.keys(object).map( (key) => {

                let encodedParts = [];

                if(Array.isArray(object[key]))
                {
                    object[key].map(function(innerKey, index){

                        encodedParts.push( encode(object[key][index], true, prefix + key + incapsulateInBrackets(index)));

                    });
                }
                else if(object[key] instanceof Object)
                {
                    Object.keys(object[key]).map( (innerKey) => {

                        if(Array.isArray(object[key][innerKey]))
                        {
                            encodedParts.push( encode(object[key][index], true, prefix + incapsulateInBrackets(key) + incapsulateInBrackets(innerKey)) );
                        }
                        else
                        {
                            encodedParts.push( prefix + incapsulateInBrackets(key) + incapsulateInBrackets(innerKey) + '=' +  object[key][innerKey] );
                        }

                    });
                }
                else
                {
                    if(isSubEncode)
                    {
                        encodedParts.push( prefix + incapsulateInBrackets(key) + '=' + object[key] );
                    }
                    else
                    {
                        encodedParts.push( key + '=' + object[key] );
                    }
                }

                return encodedParts.join('&');

            });

            return parts.join('&');
        }
于 2021-03-31T14:05:26.093 回答