625

リクエストstringを介して渡すことができるJavascript オブジェクトを にエンコードする高速で簡単な方法を知っていますか?GET

いいえjQuery、他のフレームワークはありません-単なるJavascriptです:)

4

48 に答える 48

926

このような?

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

console.log(serialize({
  foo: "hi there",
  bar: "100%"
}));
// foo=hi%20there&bar=100%25

編集:これは再帰オブジェクトも変換します(クエリ文字列にPHPの「配列」表記を使用)

serialize = function(obj, prefix) {
  var str = [],
    p;
  for (p in obj) {
    if (obj.hasOwnProperty(p)) {
      var k = prefix ? prefix + "[" + p + "]" : p,
        v = obj[p];
      str.push((v !== null && typeof v === "object") ?
        serialize(v, k) :
        encodeURIComponent(k) + "=" + encodeURIComponent(v));
    }
  }
  return str.join("&");
}

console.log(serialize({
  foo: "hi there",
  bar: {
    blah: 123,
    quux: [1, 2, 3]
  }
}));
// foo=hi%20there&bar%5Bblah%5D=123&bar%5Bquux%5D%5B0%5D=1&bar%5Bquux%5D%5B1%5D=2&bar%5Bquux%5D%5B2%5D=3

于 2009-11-11T12:31:26.380 に答える
248

jQuery にはこのための関数がありjQuery.param()ます。すでに使用している場合は、それを使用できます: http://api.jquery.com/jquery.param/

例:

var params = { width:1680, height:1050 };
var str = jQuery.param( params );

str現在含まれているwidth=1680&height=1050

于 2011-12-15T12:43:55.377 に答える
119

ES6 のワンライナーは次のとおりです。

Object.keys(obj).map(k => `${encodeURIComponent(k)}=${encodeURIComponent(obj[k])}`).join('&');
于 2016-02-15T18:14:32.720 に答える
62

Node.js v6.6.3 を使用

const querystring = require('querystring')

const obj = {
  foo: 'bar',
  baz: 'tor'
}

let result = querystring.stringify(obj)
// foo=bar&baz=tor

参考:https ://nodejs.org/api/querystring.html

于 2016-07-07T02:07:28.597 に答える
25

user187291によって受け入れられたソリューションへの小さな修正:

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が満足し、オブジェクトが単純な辞書以外の場合に、オブジェクトのメソッドやその他のものを誤ってシリアル化するのを防ぎます。このページのステートメントについては、上の段落を参照してください:http: //javascript.crockford.com/code.html

于 2013-02-26T18:50:31.150 に答える
17

さて、誰もがここに彼のワンライナーを置くようですので、ここに私のものがあります:

const encoded = Object.entries(obj).map(([k, v]) => `${k}=${encodeURIComponent(v)}`).join("&");
于 2018-03-01T21:48:19.417 に答える
12

任意のオブジェクトを送信する必要がありますか? その場合、ユーザー エージェントと Web サーバーが受け入れる URL の長さに制限があるため、GET はお勧めできません。私の提案は、送信する名前と値のペアの配列を作成してから、クエリ文字列を作成することです。

function QueryStringBuilder() {
    var nameValues = [];

    this.add = function(name, value) {
        nameValues.push( {name: name, value: value} );
    };

    this.toQueryString = function() {
        var segments = [], nameValue;
        for (var i = 0, len = nameValues.length; i < len; i++) {
            nameValue = nameValues[i];
            segments[i] = encodeURIComponent(nameValue.name) + "=" + encodeURIComponent(nameValue.value);
        }
        return segments.join("&");
    };
}

var qsb = new QueryStringBuilder();
qsb.add("veg", "cabbage");
qsb.add("vegCount", "5");

alert( qsb.toQueryString() );
于 2009-11-11T12:32:31.763 に答える
7

これは、受け入れられた回答のcoffeescriptバージョンです。これにより、誰かの時間を節約できます。

serialize = (obj, prefix) ->
  str = []
  for p, v of obj
    k = if prefix then prefix + "[" + p + "]" else p
    if typeof v == "object"
      str.push(serialize(v, k))
    else
      str.push(encodeURIComponent(k) + "=" + encodeURIComponent(v))

  str.join("&")
于 2012-08-13T17:43:48.787 に答える
6

少しは顔が良くなる

objectToQueryString(obj, prefix) {
    return Object.keys(obj).map(objKey => {
        if (obj.hasOwnProperty(objKey)) {
            const key = prefix ? `${prefix}[${objKey}]` : objKey;
            const value = obj[objKey];

            return typeof value === "object" ?
                this.objectToQueryString(value, key) :
                `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
        }

        return null;
    }).join("&");
}
于 2016-09-14T20:42:19.943 に答える
3

ネストされたオブジェクトを再帰的に変換する必要があり、オブジェクトに配列が含まれる場合と含まれない場合があります(また、配列にオブジェクトや配列が含まれる場合もあります)。ソリューションはもう少し複雑になります。これが私の試みです。

また、メインオブジェクトのどの深さでオブジェクトメンバーごとに記録するかを選択するオプションと、変換された配列からのメンバーにラベルを追加するかどうかを選択するオプションをいくつか追加しました。

理想的には、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;

}
于 2012-07-13T08:45:22.727 に答える
1

ここでいくつかのトップアンサーを見た後、いくつかのエッジケースにも取り組む別の実装を書きました

function serialize(params, prefix) {                
    return Object.entries(params).reduce((acc, [key, value]) => {
        // remove whitespace from both sides of the key before encoding
        key = encodeURIComponent(key.trim());

        if (params.constructor === Array ) {
          key = `${prefix}[]`;
        } else if (params.constructor === Object) {
          key = (prefix ? `${prefix}[${key}]` : key);
        }

        /**
         *  - undefined and NaN values will be skipped automatically
         *  - value will be empty string for functions and null
         *  - nested arrays will be flattened
         */
        if (value === null || typeof value === 'function') {
            acc.push(`${key}=`);
        } else if (typeof value === 'object') {
            acc = acc.concat(serialize(value, key));
        } else if(['number', 'boolean', 'string'].includes(typeof value) && value === value) { // self-check to avoid NaN
            acc.push(`${key}=${encodeURIComponent(value)}`);
        }

        return acc;
    }, []);
}

function objectToQueryString(queryParameters) {
    return queryParameters ? serialize(queryParameters).join('&'): '';
}

let x = objectToQueryString({
    foo: 'hello world',
    bar: {
      blah: 123,
      list: [1, 2, 3],
        'nested array': [[4,5],[6,7]] // will be flattened
    },
    page: 1,
    limit: undefined, // field will be ignored
    check: false,
    max: NaN, // field will be ignored
    prop: null,
    ' key value': 'with spaces' // space in key will be trimmed out
});
  
console.log(x); // foo=hello%20world&bar[blah]=123&bar[list][]=1&bar[list][]=2&bar[list][]=3&bar[nested%20array][][]=4&bar[nested%20array][][]=5&bar[nested%20array][][]=6&bar[nested%20array][][]=7&page=1&check=false&prop=&key%20value=with%20spaces
于 2021-05-13T09:49:08.217 に答える
0

別の方法 (再帰オブジェクトなし):

   getQueryString = function(obj)
   {
      result = "";

      for(param in obj)
         result += ( encodeURIComponent(param) + '=' + encodeURIComponent(obj[param]) + '&' );

      if(result) //it's not empty string when at least one key/value pair was added. In such case we need to remove the last '&' char
         result = result.substr(0, result.length - 1); //If length is zero or negative, substr returns an empty string [ref. http://msdn.microsoft.com/en-us/library/0esxc5wy(v=VS.85).aspx]

      return result;
   }

alert( getQueryString({foo: "hi there", bar: 123, quux: 2 }) );
于 2012-11-13T18:51:17.737 に答える
0

これは、オブジェクトを取得してクエリ パラメータ文字列に変換する簡単な実装です。

export function objectToQueryParams(queryParams: object): string {
  return queryParams ?
    Object.entries(queryParams).reduce((acc, [key, val], index) => {
      const sign = index === 0 ? '?' : '&';
      acc += `${sign}${encodeURIComponent(key)}=${encodeURIComponent(val)}`;
      return acc;
    }, '')
    : '';
}
于 2019-09-25T16:16:21.013 に答える
0

以下を使用してください:

encodeURIComponent(JSON.stringify(obj))

// elastic search example
let story ={
  "query": {
    "bool": {
      "must": [
        {
          "term": { 
            "revision.published": 0, 
          }
        },
        {
          "term": { 
            "credits.properties.by.properties.name": "Michael Guild"
          }
        },
        {
          "nested": {
            "path": "taxonomy.sections",
            "query": {
              "bool": {
                "must": [
                  {
                    "term": {
                      "taxonomy.sections._id": "/science"
                    }
                  },
                  {
                    "term": {
                      "taxonomy.sections._website": "staging"
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  }
}


const whateva = encodeURIComponent(JSON.stringify(story))
console.log(whateva)

于 2018-06-18T18:57:56.360 に答える
-1

ラムダの場合:

    R.pipe(R.toPairs, R.map(R.join('=')), R.join('&'))({a: 'b', b: 'a'})
于 2020-06-02T16:44:21.733 に答える
-1

考慮すべきクエリ文字列の長さには制限がありますが (HTTP/s GET 呼び出しで JSON データを送信する場合と POST を使用する場合) ...

JSON.stringify ( yourJSON ) は、JSON オブジェクトから文字列を作成します。

次に、それを16進エンコードします(下のリンク)。

これは、base64 タイプの URL エンコーディング、UTF-8 文字、ネストされた JSON オブジェクトなどで発生する可能性のあるさまざまな問題に対して常に機能します。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify

文字列を HEX にエンコード

于 2020-08-11T19:12:58.130 に答える