Javascript 객체의 쿼리 문자열 인코딩


481

Javascript 객체를 요청을 string통해 전달할 수 있는 빠르고 간단한 방법으로 알고 GET있습니까?

아니 jQuery, 다른 프레임 워크는 없습니다-평범한 자바 스크립트 :)


솔루션에 적합한 솔루션이있는 경우 JQuery를 솔루션으로 사용할 수없는 이유는 무엇입니까?
eaglei22

@ eaglei22 당시 IPTV 셋톱 박스 장치 프로젝트를 진행 중이었고 외부 라이브러리는 허용되지 않았기 때문입니다. ;-)
napolux 2015 년

1
답변 주셔서 감사합니다. 나는 때때로이 사양을보고 항상 시나리오를 궁금해했다. 글쎄, 지금 나는 하나를 얻었다, 감사합니다! :)
eaglei22

9
@ eaglei22 때로는 id로 하나의 요소를 얻기 위해 큰 라이브러리를로드하고 싶지 않기 때문입니다.
Aaron Harun

대부분의 브라우저는 URLSearchParams현재 지원합니다 ...
mb21 03-2012-17-17

답변:


810

이처럼?

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


2
주어진 {foo : [1,2,3], bar : "100 %"}?
Quentin

1
@Ofri : 서버에 POST 요청을 받으려면 JSON을 선택하는 것이 좋습니다. GET 요청의 경우 몇 가지 간단한 매개 변수 이외의 것을 서버로 보내면 디자인이 잘못되었을 수 있습니다.
Tim Down

2
@Marcel 함수가 hasOwnProperty를 확인하지 않기 때문입니다. 나는 지금 당신의 바이올린을 업데이트했습니다 : jsfiddle.net/rudiedirkx/U5Tyb/1
Rudie

1
@TimDown GET 요청에서 간단한 매개 변수를 보내는 의견과 관련하여. 난 동의하지 않는다. 서버 측의 PHP가 준비된 연관 배열을 찾으면 매개 변수를 배열로 그룹화하는 것이 편리 할 수 ​​있습니다. 왜 이것이 디자인으로 잘못되었는지 알 수 없습니다.
Savas Vedova

1
'if (obj.hasOwnProperty (prop))'가 필요합니까? for in 문은 객체의 속성 바로 위의 루프이므로 hasOwnProperty를 호출하면 항상 true로 평가됩니다.
Arnon

231

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


119
Napolux (OP) 인용 : "그냥 평범한 자바 스크립트" . : P
Sk8erPeter

6
jQuery.param ()에는 불쾌한 동작이 있습니다. var a = []; a [2564] = 12; console.log (jQuery.param ({속성 목록 : a})); 무슨 뜻인지 알기 위해
akond

13
@akond jQuery 문서는 구체적으로 베어 배열로 전달할 수 없다고 말합니다.
Ariel

4
@ 아리엘 그는 베어 배열로 전달하지 않습니다. 그는 인덱스 2564에 하나의 값만있는 배열을 전달하고 있습니다. var a = []; a[5] = 'foo'; jQuery.param({ parameters: a }); 결과 : "parameters[]=&parameters[]=&parameters[]=&parameters[]=&parameters[]=&parameters[]=foo". 어느 것이 맞지만 예상치 못한 것일 수 있습니다.
Chris Hall

4
질문이 구체적으로 물었습니다 Vanilla JS
Bug Hunter 219

188

그냥 사용하십시오 URLSearchParams이것은 모든 현재 브라우저에서 작동합니다

new URLSearchParams(object).toString()

5
재귀 객체를 수행하지 않으므로 아니오
Eddie Monge Jr

중첩 된 객체에서는 작동하지 않습니다. let j = { m: 5, n: { k: 1 } }; new URLSearchParams(j).toString(); // result "m=5&n=%5Bobject+Object%5D"
hitautodestruct 8:14에

19
@EddieMongeJr 쿼리 문자열은 설계 상 키-값 쌍이므로 중첩 된 개체를 직렬화하지 않아도됩니다.이 답변은 현대적인 방법입니다. 공감 필요.
Romain Durand

5
예, 키 값 쌍이지만 값이 문자열로 인코딩 된 객체 일 수 없다는 것은 없습니다. 또한, 원래의 질문에 중첩 특성을 가질 수 있습니다 "문자열로 자바 스크립트 객체"요청
에디 몽주 주니어

@EddieMongeJr 심지어 받아 들일 수있는 대답 (그리고 잠시 후에 다른 것)은 중첩 된 객체를 지원하지 않습니다. 할 수 있습니다 stringify에 중첩 된 객체 당신이 할 수있는 전URLSearchParams
MOSH Feu하십시오

128
Object.keys(obj).reduce(function(a,k){a.push(k+'='+encodeURIComponent(obj[k]));return a},[]).join('&')

편집 : 나는이 한 줄짜리를 좋아하지만 허용 된 대답과 의미 적으로 일치하면 더 인기있는 답변 일 것입니다.

function serialize( obj ) {
    let str = '?' + Object.keys(obj).reduce(function(a, k){
        a.push(k + '=' + encodeURIComponent(obj[k]));
        return a;
    }, []).join('&');
    return str;
}

1
환원 기능 전용 라인은 가독성을 크게 향상시킵니다.
Aurelien Ribon

54
.reduce () 대신 .map ()을 사용하는 것이 훨씬 간단합니다. Object.keys(obj).map(k => k + '=' + encodeURIComponent(obj[k])).join('&')
Jannes

2
그냥 참고로 그 Object.keysIE에서> = 9 만 사용할 수 있습니다
존스턴

5
연결 대신 ES6 템플릿을 사용하여 @Jannes 코드를 개선했습니다.Object.keys(obj).map(k => `${k}=${encodeURIComponent(obj[k])}`).join('&')
csilk

1
키에 encodeUriComponent ❤️이 필요한 경우 : Object.entries(obj).map(e => e.map(ee => encodeURIComponent(ee)).join('=')).join('&');
Blaise

112

ES6의 하나의 라이너는 다음과 같습니다.

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

k / k로 키를 교체하고 황금입니다
Jamie Kudla

17
경고! 얕은 물체에서만 작동합니다. 다른 개체 인 최상위 속성이있는 경우이 한 라이너는 "key = % 5Bobject % 20Object % 5D"를 출력합니다. 머릿결처럼.
Andrew Allbright

4
또한 이것은 배열을 뱉어 내지 않습니다. 나는 끔찍한 표준이 export?actions[]=finance,create,edit있어야 할 때를 얻었습니다 export?actions[]=finance&actions[]=create&actions[]=edit.
darkbluesun

3
URL 인수는 사양에 관한 한 문자열 일 뿐이므로 배열은 항상 "자신 만의 것"입니다. 따라서 단일 문자열이 아닌 모든 것을 서버에서 올바르게 읽을 수있게됩니다. 당신은 전화하고 있습니다. actions[]PHP 표기법입니다. Django는 action대신 다중을 사용합니다 ( []접미사 없음 ). 다른 일부 ORM / CMS에는 쉼표로 구분 된 목록 등이 필요합니다. "단순한 문자열이 아닌 경우 먼저 서버가 원하는 것을 알아야합니다".
Mike 'Pomax'Kamermans

매우 우아한 솔루션!
Anh Tran


43

URLSearchParams인터페이스를 사용하는 것이 좋습니다 .

const searchParams = new URLSearchParams();
const search = {foo: "hi there", bar: "100%" };
Object.keys(search).forEach(key => searchParams.append(key, search[key]));
console.log(searchParams.toString())

또는 검색 객체를 다음과 같이 생성자에 전달하여 :

const obj = {foo: "hi there", bar: "100%" };
const params = new URLSearchParams(obj).toString();

1
흥미로운 제안이지만이 기능에 대한 브라우저 지원은 여전히 ​​엉망입니다.
mrec

IE (현재는 일반적 임)와 일부 특정 모바일 버전을 지원하지 않을 경우 일반 JavaScript이므로 이것이 가장 좋은 대답입니다.
Marcos Sandrini

24

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


14

글쎄, 모두 여기에 하나의 라이너를 넣는 것 같습니다.

const encoded = Object.entries(obj).map(([k, v]) => `${k}=${encodeURIComponent(v)}`).join("&");

1
IE에서는 Object.entries가 지원되지 않습니다.
MBouwman

@MBouwman, 물론 IE는 선과 악을 넘어서고 있습니다. 그래서 babel / core-js를 사용해야하는 이유
chpio

@chpio Babel / core-js는 내가 옳다면 Object.entries를 지원하지 않습니다.
MBouwman

코어는 Object.entries에 대한 지원이 있습니다 github.com/zloirock/core-js/blob/master/... 런타임 바벨 corejs2 심지어 이전 변환을 지원합니까 그것뿐만 아니라 github.com/babel/babel/blob/...
chpio

12

임의의 객체를 보내야합니까? 그렇다면 사용자 에이전트와 웹 서버가 허용 할 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() );

11

레일즈 / PHP 스타일 쿼리 빌더

이 메소드는 Javascript 객체를로 변환합니다 URI Query String. 또한 중첩 배열하고 (오브젝트의 핸들 Rails/ PHP구)

function serializeQuery(params, prefix) {
  const query = Object.keys(params).map((key) => {
    const value  = params[key];

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

    if (typeof value === 'object')
      return serializeQuery(value, key);
    else
      return `${key}=${encodeURIComponent(value)}`;
  });

  return [].concat.apply([], query).join('&');
}

사용법 예 :

let params = {
  a: 100,
  b: 'has spaces',
  c: [1, 2, 3],
  d: { x: 9, y: 8}
}

serializeQuery(params)
// returns 'a=100&b=has%20spaces&c[]=1&c[]=2&c[]=3&d[x]=9&d[y]=8

좋은 예입니다. 나는 당신의 대답에 오타를 고쳤습니다. 그건 그렇고, 당신 functionfalsy값 을 제외하도록 편집하면 흥미로울 것입니다 (null, undefined, NaN, '') ...
developer033

8

JSON을 사용하십시오.

구현 방법에 대한 아이디어를 얻으려면 이 질문 을 살펴보십시오 .


2
그가 서버에 무엇을 쓰고 있는지 모르겠지만 대부분의 현대 언어에는 JSON을 읽는 좋은 패키지가 있습니다. 또한 구현을 끝내더라도 새로운 인코딩 체계를 개발하는 것보다 JSON 읽기 서버 코드를 구현하는 것이 좋습니다. 이와 같은 DIY 인코딩은 버그가있는 경향이 있습니다 (일반적으로 값 자체가 배열 인 것처럼 모든 가능한 경우를 생각하지 않기 때문입니다).
Ofri Raviv

기본적으로 객체를 JSON으로 변환 한 다음 전체 JSON 문자열을 단일 GET 쿼리 매개 변수로 서버에 전달하도록 제안하고 있습니까?
Marco Demaio

8

허용되는 답변의 커피 스크립트 버전은 다음과 같습니다. 누군가에게 시간을 절약 할 수 있습니다.

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("&")

감사합니다 alfonso! 정말 내 시간을 구했다!
루카스

6

Object.entries 가 포함 된 간결하고 재귀적인 버전입니다 . 임의로 중첩 된 배열은 처리하지만 중첩 된 객체는 처리하지 않습니다. 또한 빈 요소를 제거합니다.

const format = (k,v) => v !== null ? `${k}=${encodeURIComponent(v)}` : ''

const to_qs = (obj) => {
    return [].concat(...Object.entries(obj)
                       .map(([k,v]) => Array.isArray(v) 
                          ? v.map(arr => to_qs({[k]:arr})) 
                          : format(k,v)))
           .filter(x => x)
           .join('&');
}

예 :

let json = { 
    a: [1, 2, 3],
    b: [],              // omit b
    c: 1,
    d: "test&encoding", // uriencode
    e: [[4,5],[6,7]],   // flatten this
    f: null,            // omit nulls
    g: 0
};

let qs = to_qs(json)

=> "a=1&a=2&a=3&c=1&d=test%26encoding&e=4&e=5&e=6&e=7&g=0"

이 버전은 중첩 배열을 다룰 때 나를 위해 일했습니다. Ruby / PHP 스타일 배열 키를 사용하기 위해 약간의 조정이 있었지만 그렇지 않으면 훌륭하게 작동합니다.
nickb

5

이것은 null / undefined 값을 건너 뜁니다.

export function urlEncodeQueryParams(data) {
    const params = Object.keys(data).map(key => data[key] ? `${encodeURIComponent(key)}=${encodeURIComponent(data[key])}` : '');
    return params.filter(value => !!value).join('&');
}

5

ES7에서는 이것을 한 줄로 작성할 수 있습니다 :

const serialize = (obj) => (Object.entries(obj).map(i => [i[0], encodeURIComponent(i[1])].join('=')).join('&'))

4

누군가가 다시 필요로 할 경우 Object를 Query String으로 변환하는 단일 행

let Objs = { a: 'obejct-a', b: 'object-b' }

Object.keys(objs).map(key => key + '=' + objs[key]).join('&')

// result will be a=object-a&b=object-b

4

타사 라이브러리를 사용하지 않고 "Object.keys"(일명 모든 최신 브라우저 + edge + 즉)가있는 브라우저에서 이미 사용하기 쉬운 간단한 솔루션이 있습니다.

ES5에서

function(a){
    if( typeof(a) !== 'object' ) 
        return '';
    return `?${Object.keys(a).map(k=>`${k}=${a[k]}`).join('&')}`;
}

ES3에서

function(a){
    if( typeof(a) !== 'object' ) 
        return '';
    return '?' + Object.keys(a).map(function(k){ return k + '=' + a[k] }).join('&');
}

3

중첩 된 객체를 재귀 적으로 변환하고 객체가 배열을 포함하거나 포함하지 않을 경우 (및 배열에 객체 또는 배열 등이 포함될 수있는 경우) 솔루션이 조금 더 복잡해집니다. 이것은 나의 시도이다.

또한 주 개체의 깊이에 따라 각 개체 구성원에 대해 기록하고 변환 된 배열에서 가져온 구성원에 레이블을 추가할지 여부를 선택할 수있는 몇 가지 옵션을 추가했습니다.

이상적으로는 매개 변수가 실제로 객체 또는 배열을 수신하는지 테스트해야합니다.

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;

}

재귀 접근에 감사드립니다
Sherlock

3

허용되는 솔루션을 추가하면 객체 및 객체 배열과 함께 작동합니다.

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

asp.net mvc 작업 방법과 같은 객체 매개 변수를 사용하는 경우 objName도 추가했습니다.


3

조금 더 좋아 보인다

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("&");
}

3

내가 만든 JSON의 stringifiers의 비교 및 결과는 다음과 같다 :

JSON:    {"_id":"5973782bdb9a930533b05cb2","isActive":true,"balance":"$1,446.35","age":32,"name":"Logan Keller","email":"logankeller@artiq.com","phone":"+1 (952) 533-2258","friends":[{"id":0,"name":"Colon Salazar"},{"id":1,"name":"French Mcneil"},{"id":2,"name":"Carol Martin"}],"favoriteFruit":"banana"}
Rison:   (_id:'5973782bdb9a930533b05cb2',age:32,balance:'$1,446.35',email:'logankeller@artiq.com',favoriteFruit:banana,friends:!((id:0,name:'Colon Salazar'),(id:1,name:'French Mcneil'),(id:2,name:'Carol Martin')),isActive:!t,name:'Logan Keller',phone:'+1 (952) 533-2258')
O-Rison: _id:'5973782bdb9a930533b05cb2',age:32,balance:'$1,446.35',email:'logankeller@artiq.com',favoriteFruit:banana,friends:!((id:0,name:'Colon Salazar'),(id:1,name:'French Mcneil'),(id:2,name:'Carol Martin')),isActive:!t,name:'Logan Keller',phone:'+1 (952) 533-2258'
JSURL:   ~(_id~'5973782bdb9a930533b05cb2~isActive~true~balance~'!1*2c446.35~age~32~name~'Logan*20Keller~email~'logankeller*40artiq.com~phone~'*2b1*20*28952*29*20533-2258~friends~(~(id~0~name~'Colon*20Salazar)~(id~1~name~'French*20Mcneil)~(id~2~name~'Carol*20Martin))~favoriteFruit~'banana)
QS:      _id=5973782bdb9a930533b05cb2&isActive=true&balance=$1,446.35&age=32&name=Logan Keller&email=logankeller@artiq.com&phone=+1 (952) 533-2258&friends[0][id]=0&friends[0][name]=Colon Salazar&friends[1][id]=1&friends[1][name]=French Mcneil&friends[2][id]=2&friends[2][name]=Carol Martin&favoriteFruit=banana
URLON:   $_id=5973782bdb9a930533b05cb2&isActive:true&balance=$1,446.35&age:32&name=Logan%20Keller&email=logankeller@artiq.com&phone=+1%20(952)%20533-2258&friends@$id:0&name=Colon%20Salazar;&$id:1&name=French%20Mcneil;&$id:2&name=Carol%20Martin;;&favoriteFruit=banana
QS-JSON: isActive=true&balance=%241%2C446.35&age=32&name=Logan+Keller&email=logankeller%40artiq.com&phone=%2B1+(952)+533-2258&friends(0).id=0&friends(0).name=Colon+Salazar&friends(1).id=1&friends(1).name=French+Mcneil&friends(2).id=2&friends(2).name=Carol+Martin&favoriteFruit=banana

그중 가장 짧은 것이 URL Object Notation 입니다.


2

좋아, 그것은 오래된 게시물이지만이 문제에 직면하고 있으며 내 개인적인 해결책을 찾았습니다 .. 어쩌면 다른 사람을 도울 수 있습니다 ..

     function objToQueryString(obj){
        var k = Object.keys(obj);
        var s = "";
        for(var i=0;i<k.length;i++) {
            s += k[i] + "=" + encodeURIComponent(obj[k[i]]);
            if (i != k.length -1) s += "&";
        }
        return s;
     };

2

중첩 된 객체가 많은 경우 위의 답변 채우기가 작동하지 않습니다. 대신 여기에서 함수 매개 변수를 선택할 수 있습니다-https: //github.com/knowledgecode/jquery-param/blob/master/jquery-param.js 그것은 나를 위해 아주 잘 작동했습니다!

    var param = function (a) {
    var s = [], rbracket = /\[\]$/,
        isArray = function (obj) {
            return Object.prototype.toString.call(obj) === '[object Array]';
        }, add = function (k, v) {
            v = typeof v === 'function' ? v() : v === null ? '' : v === undefined ? '' : v;
            s[s.length] = encodeURIComponent(k) + '=' + encodeURIComponent(v);
        }, buildParams = function (prefix, obj) {
            var i, len, key;

            if (prefix) {
                if (isArray(obj)) {
                    for (i = 0, len = obj.length; i < len; i++) {
                        if (rbracket.test(prefix)) {
                            add(prefix, obj[i]);
                        } else {
                            buildParams(prefix + '[' + (typeof obj[i] === 'object' ? i : '') + ']', obj[i]);
                        }
                    }
                } else if (obj && String(obj) === '[object Object]') {
                    for (key in obj) {
                        buildParams(prefix + '[' + key + ']', obj[key]);
                    }
                } else {
                    add(prefix, obj);
                }
            } else if (isArray(obj)) {
                for (i = 0, len = obj.length; i < len; i++) {
                    add(obj[i].name, obj[i].value);
                }
            } else {
                for (key in obj) {
                    buildParams(key, obj[key]);
                }
            }
            return s;
        };

    return buildParams('', a).join('&').replace(/%20/g, '+');
};

2

자바 객체의 쿼리 문자열 쿼리에 대한 ES6 솔루션

const params = {
  a: 1,
  b: 'query stringify',
  c: null,
  d: undefined,
  f: '',
  g: { foo: 1, bar: 2 },
  h: ['Winterfell', 'Westeros', 'Braavos'],
  i: { first: { second: { third: 3 }}}
}

static toQueryString(params = {}, prefix) {
  const query = Object.keys(params).map((k) => {
    let key = k;
    const value = params[key];

    if (!value && (value === null || value === undefined || isNaN(value))) {
      value = '';
    }

    switch (params.constructor) {
      case Array:
        key = `${prefix}[]`;
        break;
      case Object:
        key = (prefix ? `${prefix}[${key}]` : key);
        break;
    }

    if (typeof value === 'object') {
      return this.toQueryString(value, key); // for nested objects
    }

    return `${key}=${encodeURIComponent(value)}`;
  });

  return query.join('&');
}

toQueryString (매개 변수)

"a=1&b=query%20stringify&c=&d=&f=&g[foo]=1&g[bar]=2&h[]=Winterfell&h[]=Westeros&h[]=Braavos&i[first][second][third]=3"

2

이것은 .NET 백엔드에서 즉시 작동하는 솔루션입니다. 이 스레드의 기본 답변을 취하여 .NET 요구에 맞게 업데이트했습니다.

function objectToQuerystring(params) {
var result = '';

    function convertJsonToQueryString(data, progress, name) {
        name = name || '';
        progress = progress || '';
        if (typeof data === 'object') {
            Object.keys(data).forEach(function (key) {
                var value = data[key];
                if (name == '') {
                    convertJsonToQueryString(value, progress, key);
                } else {
                    if (isNaN(parseInt(key))) {
                        convertJsonToQueryString(value, progress, name + '.' + key);
                    } else {
                        convertJsonToQueryString(value, progress, name + '[' + key+ ']');
                    }
                }
            })
        } else {
            result = result ? result.concat('&') : result.concat('?');
            result = result.concat(`${name}=${data}`);
        }
    }

    convertJsonToQueryString(params);
    return result;
}

1

나는 그것을 위해 패키지를 작성했다 : object-query-string :)

중첩 된 객체, 배열, 사용자 정의 인코딩 기능 등을 지원합니다. 경량 및 jQuery는 무료입니다.

// TypeScript
import { queryString } from 'object-query-string';

// Node.js
const { queryString } = require("object-query-string");

const query = queryString({
    filter: {
        brands: ["Audi"],
        models: ["A4", "A6", "A8"],
        accidentFree: true
    },
    sort: 'mileage'
});

보고

filter[brands][]=Audi&filter[models][]=A4&filter[models][]=A6&filter[models][]=A8&filter[accidentFree]=true&sort=milage

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

0

답변 @ user187291에서 "isArray"를 매개 변수로 추가하여 json 중첩 배열을 변환하십시오.

data : {
                    staffId : "00000001",
                    Detail : [ {
                        "identityId" : "123456"
                    }, {
                        "identityId" : "654321"
                    } ],

                }

결과를 얻으려면 :

staffId = 00000001 & Detail [0] .identityId = 123456 & Detail [1] .identityId = 654321

serialize = function(obj, prefix, isArray) {
        var str = [],p = 0;
        for (p in obj) {
            if (obj.hasOwnProperty(p)) {
                var k, v;
                if (isArray)
                    k = prefix ? prefix + "[" + p + "]" : p, v = obj[p];
                else
                    k = prefix ? prefix + "." + p + "" : p, v = obj[p];

                if (v !== null && typeof v === "object") {
                    if (Array.isArray(v)) {
                        serialize(v, k, true);
                    } else {
                        serialize(v, k, false);
                    }
                } else {
                    var query = k + "=" + v;
                    str.push(query);
                }
            }
        }
        return str.join("&");
    };

    serialize(data, "prefix", false);

0

간단한 JavaScript 를 사용하여이를 달성 할 수도 있습니다 .

const stringData = '?name=Nikhil&surname=Mahirrao&age=30';
    
const newData= {};
stringData.replace('?', '').split('&').map((value) => {
  const temp = value.split('=');
  newData[temp[0]] = temp[1];
});

console.log('stringData: '+stringData);
console.log('newData: ');
console.log(newData);


1
이것은 좋은 운동이지만, 다른 방법입니다. 질문에 대한 답변이 아닙니다.
Christiaan Westerbeek
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.