是否有一个快速和简单的方法来编码JavaScript对象到字符串,我可以通过GET请求传递?

没有jQuery,没有其他框架-只有纯JavaScript:)


当前回答

对用户187291接受的解决方案的一个小修改:

serialize = function(obj) {
   var str = [];
   for(var p in obj){
       if (obj.hasOwnProperty(p)) {
           str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
       }
   }
   return str.join("&");
}

检查对象上的hasOwnProperty使JSLint和JSHint高兴,它防止意外序列化对象的方法或其他东西,如果对象不是一个简单的字典。有关JavaScript编程语言的代码约定的语句,请参阅上一段。

其他回答

如果您想递归地转换嵌套对象,并且对象可能包含也可能不包含数组(数组可能包含对象或数组等),那么解决方案就会变得稍微复杂一些。这就是我的尝试。

我还添加了一些选项,用于选择是否要为每个对象成员记录它位于主对象中的深度,以及选择是否要向来自已转换数组的成员添加标签。

理想情况下,您应该测试thing参数是否真的接收到对象或数组。

function thingToString(thing,maxDepth,recordLevel,markArrays){
    //thing: object or array to be recursively serialized
    //maxDepth (int or false):
    // (int) how deep to go with converting objects/arrays within objs/arrays
    // (false) no limit to recursive objects/arrays within objects/arrays
    //recordLevel (boolean):
    //  true - insert "(level 1)" before transcript of members at level one (etc)
    //  false - just 
    //markArrays (boolean):
    //  insert text to indicate any members that came from arrays
    var result = "";
    if (maxDepth !== false && typeof maxDepth != 'number') {maxDepth = 3;}
    var runningDepth = 0;//Keeps track how deep we're into recursion

    //First prepare the function, so that it can call itself recursively
    function serializeAnything(thing){
        //Set path-finder values
        runningDepth += 1;
        if(recordLevel){result += "(level " + runningDepth + ")";}

        //First convert any arrays to object so they can be processed
        if (thing instanceof Array){
            var realObj = {};var key;
            if (markArrays) {realObj['type'] = "converted array";}
            for (var i = 0;i < thing.length;i++){
                if (markArrays) {key = "a" + i;} else {key = i;}
                realObj[key] = thing[i];
            }
            thing = realObj;
            console.log('converted one array to ' + typeof realObj);
            console.log(thing);
        }

        //Then deal with it
        for (var member in thing){
            if (typeof thing[member] == 'object' && runningDepth < maxDepth){
                serializeAnything(thing[member]);
                //When a sub-object/array is serialized, it will add one to
                //running depth. But when we continue to this object/array's
                //next sibling, the level must go back up by one
                runningDepth -= 1;
            } else if (maxDepth !== false && runningDepth >= maxDepth) {
                console.log('Reached bottom');
            } else 
            if (
                typeof thing[member] == "string" || 
                typeof thing[member] == 'boolean' ||
                typeof thing[member] == 'number'
            ){
                result += "(" + member + ": " + thing[member] + ") ";
            }  else {
                result += "(" + member + ": [" + typeof thing[member] + " not supported]) ";
            }
        }
    }
    //Actually kick off the serialization
    serializeAnything(thing);

    return result;

}

以更好的方式做这件事。

它可以处理标准查询形式的递归对象或数组,如a=val&b[0]=val&b[1]=val&c=val&d[some key]=val。这是最后一个函数。

逻辑、功能

const objectToQueryString = (initialObj) => {
  const reducer = (obj, parentPrefix = null) => (prev, key) => {
    const val = obj[key];
    key = encodeURIComponent(key);
    const prefix = parentPrefix ? `${parentPrefix}[${key}]` : key;

    if (val == null || typeof val === 'function') {
      prev.push(`${prefix}=`);
      return prev;
    }

    if (['number', 'boolean', 'string'].includes(typeof val)) {
      prev.push(`${prefix}=${encodeURIComponent(val)}`);
      return prev;
    }

    prev.push(Object.keys(val).reduce(reducer(val, prefix), []).join('&'));
    return prev;
  };

  return Object.keys(initialObj).reduce(reducer(initialObj), []).join('&');
};

例子

const testCase1 = {
  name: 'Full Name',
  age: 30
}

const testCase2 = {
  name: 'Full Name',
  age: 30,
  children: [
    {name: 'Child foo'},
    {name: 'Foo again'}
  ],
  wife: {
    name: 'Very Difficult to say here'
  }
}

console.log(objectToQueryString(testCase1));
console.log(objectToQueryString(testCase2));

现场测试

展开下面的代码片段,在浏览器中验证结果-

const objectToQueryString = (initialObj) => { const reducer = (obj, parentPrefix = null) => (prev, key) => { const val = obj[key]; key = encodeURIComponent(key); const prefix = parentPrefix ? `${parentPrefix}[${key}]` : key; if (val == null || typeof val === 'function') { prev.push(`${prefix}=`); return prev; } if (['number', 'boolean', 'string'].includes(typeof val)) { prev.push(`${prefix}=${encodeURIComponent(val)}`); return prev; } prev.push(Object.keys(val).reduce(reducer(val, prefix), []).join('&')); return prev; }; return Object.keys(initialObj).reduce(reducer(initialObj), []).join('&'); }; const testCase1 = { name: 'Full Name', age: 30 } const testCase2 = { name: 'Full Name', age: 30, children: [ {name: 'Child foo'}, {name: 'Foo again'} ], wife: { name: 'Very Difficult to say here' } } console.log(objectToQueryString(testCase1)); console.log(objectToQueryString(testCase2));

需要考虑的事情。

它跳过函数、null和未定义的值 它跳过空对象和数组的键和值。 它不处理用new Number(1)或new String('my String ')创建的Number或String对象,因为没有人应该这样做

可以将具有未定义属性的对象传递给此函数。如果属性存在,它将被转换为查询字符串并返回查询字符串。

函数convertToQueryString(props) { const objQueryString ={…道具}; for (objQueryString中的const键){ If (!key) { 删除objQueryString(例子); } } const params = JSON.stringify(objQueryString); Const qs =参数 .replace (/[/''""{}]/ 克,”) .replace (/ [:] / g, ' = ') .replace (/, / g, ' & '); console.log (qs) 返回qs; } convertToQueryString({order: undefined, limit: 5, page: 1})

PHP符号的TypeScript版本(没有URL转义版本)

/**
 * Converts an object into a Cookie-like string.
 * @param toSerialize object or array to be serialized
 * @param prefix used in deep objects to describe the final query parameter
 * @returns ampersand separated key=value pairs
 *
 * Example:
 * ```js
 * serialize({hello:[{world: "nice"}]}); // outputs  "hello[0][world]=nice"
 * ```
 * ---
 * Adapted to TS from a StackOverflow answer https://stackoverflow.com/a/1714899/4537906
 */
const serialize = (toSerialize: unknown = {}, prefix?: string) => {
  const keyValuePairs = [];

  Object.keys(toSerialize).forEach((attribute) => {
    if (Object.prototype.hasOwnProperty.call(toSerialize, attribute)) {
      const key = prefix ? `${prefix}[${attribute}]` : attribute;
      const value = toSerialize[attribute];
      const toBePushed =
        value !== null && typeof value === "object"
          ? serialize(value, key)
          : `${key}=${value}`;
      keyValuePairs.push(toBePushed);
    }
  });

  return keyValuePairs.join("&");
};
const serialize = obj => Object.keys(obj).reduce((a, b) =>
    a.push(encodeURIComponent(b) + "=" + encodeURIComponent(obj[b])) && a,
    []).join("&");

电话:

console.log(serialize({a:1,b:2}));
// output: 'a=1&b=2

'