URL क्वेरी पैरामीटर की सूची में किसी ऑब्जेक्ट को क्रमबद्ध कैसे करें?


148

एक जावास्क्रिप्ट की कुंजी जानने के बिना Object, मैं कुछ कैसे बदल सकता हूं ...

var obj = {
   param1: 'something',
   param2: 'somethingelse',
   param3: 'another'
}

obj[param4] = 'yetanother';

... में ...

var str = 'param1=something&param2=somethingelse&param3=another&param4=yetanother';

...?


क्या आप एक पुनरावर्ती समाधान की तलाश कर रहे हैं?
जेरेड फरिश

1
@ Jared मैंने एक पुनरावर्ती समाधान जोड़ा :) :)
एलेक्स

@alex - धन्यवाद; मुझे अधिक जटिल समस्याओं पर अधिक अनुभवी लोक से जवाब देखना पसंद है। :)
जारेड फरिश

2
@ आप जानते हैं, मैं वास्तव में एक अनुभवी जावास्क्रिप्ट डेवलपर के रूप में खुद के बारे में कभी नहीं सोचता । हैक की तरह अधिक तिल यह आदमी काम करता है :)
एलेक्स

@alex - ओह हाँ, मैं भी। लेकिन आप किस तरह से एक साथ डालेंगे, मैं इसकी तुलना कैसे करूंगा? मैं लगातार चकित हूं।
जारेड फरिश जूल

जवाबों:


104
var str = "";
for (var key in obj) {
    if (str != "") {
        str += "&";
    }
    str += key + "=" + encodeURIComponent(obj[key]);
}

उदाहरण: http://jsfiddle.net/WFPen/


3
पुनरावृत्ति के साथ एक फ़ंक्शन का उपयोग क्यों नहीं करें?
जारेड फरिश जूल

1
धन्यवाद @ अमर! मैंने केवल आपके ऊपर @ patrick के उत्तर को स्वीकार किया है (वे मूल रूप से समान हैं) क्योंकि वह पहले था, मुझे विश्वास है। मैं आपकी प्रतिक्रिया के लिए बहुत आभारी हूं।
1

4
@bobsoap: मुझे लगता है कि @aroth मुझसे थोड़ा आगे था, इसलिए मैं @aroth को अन्य सभी चीजों के बराबर होने पर टिक दूंगा।
user113716

3
क्या obj [key] को encodeURIComponent () में नहीं लपेटा जाना चाहिए? यदि 'कुछ ’कुछ? कुछ और’ था तो क्या होगा?
जेम्स एस

1
मुझे पूरा यकीन है कि यह स्वीकृत जवाब नहीं होना चाहिए , या इस स्टैकओवरफ़्लो थ्रेड पर लगभग हर उत्तर होना चाहिए । प्राथमिक कारण उनमें से कोई भी नहीं हो सकता है अपवाद के साथ @ zac का जवाब नीचे इस ऑब्जेक्ट को अच्छी तरह से एन्कोडिंग करने से संतुष्ट होगा, { a:[ 1, 2 ], b:{ c:3, d:[ 4, 5 ], e:{ x:[ 6 ], y:7, z:[ 8, 9 ] }, f:true, g:false, h:undefined }, i:[ 10, 11 ], j:true, k:false, l:[ undefined, 0 ], m:"cowboy hat?" };ऐसा लगता है कि @UnLoCo ने एक NPM लाइब्रेरी का सुझाव दिया है जो भी काम करेगा, जो स्टैंडअलोन होने के लिए jQuery के कामकाज परम विधि को खींचता है।
वेस

128

यदि आप jQuery का उपयोग करते हैं, तो यह GET ajax अनुरोध के विकल्पों को पैरामीटर करने के लिए उपयोग करता है:

$.param( obj )

http://api.jquery.com/jQuery.param/


120

एक सुरुचिपूर्ण एक: (यह मानते हुए कि आप एक आधुनिक ब्राउज़र या नोड चला रहे हैं)

var str = Object.keys(obj).map(function(key) {
  return key + '=' + obj[key];
}).join('&');

और ES2017 समकक्ष: (लुकास के लिए धन्यवाद)

let str = Object.entries(obj).map(([key, val]) => `${key}=${val}`).join('&');

नोट: आप शायद उपयोग करना चाहते हैं encodeURIComponent()यदि कुंजी / मान URL एनकोडेड नहीं हैं।


50
मैं केवल + encodeURIComponent(obj[key])
बदलूंगा

1
@JacobValenta सवाल का हिस्सा नहीं है
9

5
यहाँ यह ES2015 में हैObject.entries(obj).map(([key, val]) => `${key}=${val}`).join('&')
लुकास

2
यह टूट जाता है यदि ऑब्जेक्ट में कोई नेस्टेड गुण हैं।
बीन

2
ES2015 उत्तर परिवर्तन को सांकेतिक शब्दों में बदलना:=${encodeURIComponent(val)}
BBlackwo

49

इस बारे में कैसा है? यह एक पंक्ति है और कोई निर्भरता नहीं है:

new URLSearchParams(obj).toString();
// OUT: param1=something&param2=somethingelse&param3=another&param4=yetanother

URL URL के साथ इसका उपयोग करें जैसे:

let obj = { param1: 'something', param2: 'somethingelse', param3: 'another' }
obj['param4'] = 'yetanother';
const url = new URL(`your_url.com`);
url.search = new URLSearchParams(obj);
const response = await fetch(url);

[4 अप्रैल, 2020 संपादित करें]: जैसा कि टिप्पणियों में उल्लेख किया गया है nullमानों को एक स्ट्रिंग के रूप में व्याख्या किया जाएगा 'null'। इसलिए अशक्त भावों से सावधान रहें।


10
यह एक मील द्वारा सबसे अच्छा जवाब है
hraban

नोट: नोड <10 में आपको आयात / आवश्यकता की आवश्यकता होगी जैसे,const { URLSearchParams } = require("url");
ग्रूवोडकर

1
@HonsaStunna मैंने कभी भी URL पैरामीटर पर बहुआयामी वस्तुओं को रखने के बारे में नहीं सोचा है, आमतौर पर JSON के साथ POST का उपयोग करते हैं
jfunk

1
इस एक और अशक्त मूल्यों से सावधान रहें।
ज़ाराक्सिया



19

एक स्तर के लिए गहरी ...

var serialiseObject = function(obj) {
    var pairs = [];
    for (var prop in obj) {
        if (!obj.hasOwnProperty(prop)) {
            continue;
        }
        pairs.push(prop + '=' + obj[prop]);
    }
    return pairs.join('&');
}

jsFiddle

मनमाने ढंग से गहरी वस्तुओं के लिए एक पुनरावर्ती कार्य के बारे में बात की गई थी ...

var serialiseObject = function(obj) {
    var pairs = [];
    for (var prop in obj) {
        if (!obj.hasOwnProperty(prop)) {
            continue;
        }
        if (Object.prototype.toString.call(obj[prop]) == '[object Object]') {
            pairs.push(serialiseObject(obj[prop]));
            continue;
        }
        pairs.push(prop + '=' + obj[prop]);
    }
    return pairs.join('&');
}

jsFiddle

यह निश्चित रूप से इसका मतलब है कि क्रमांकन में घोंसले के शिकार का संदर्भ खो गया है।

यदि मान URL के साथ शुरू करने के लिए एन्कोडेड नहीं हैं, और आप उन्हें URL में उपयोग करने का इरादा रखते हैं, तो जावास्क्रिप्ट की जाँच करें encodeURIComponent()


1
एलेक्स: क्षमा करें, हम बंद कर रहे हैं ...; ओ)
user113716

+1 अधिक सुरक्षित होने के कारण मैं इसके लिए तैयार हूं .hasOwnProperty(prop):।
user113716

यह बहुत अच्छा है - अभी के लिए केवल 1 स्तर की आवश्यकता है, लेकिन पुनरावर्ती कार्य करना अच्छा है। इसे जोड़ने के लिए धन्यवाद!
1

1
@ ripper234 आप उस विधि का उपयोग नहीं करने के लिए स्वतंत्र हैं, यदि यह आपकी आवश्यकताओं के अनुरूप है।
एलेक्स


5

सिर्फ रिकॉर्ड के लिए और यदि आपके पास ES6 का समर्थन करने वाला कोई ब्राउज़र है, तो यहां एक समाधान है reduce:

Object.keys(obj).reduce((prev, key, i) => (
  `${prev}${i!==0?'&':''}${key}=${obj[key]}`
), '');

और यहाँ कार्रवाई में एक स्निपेट है!

// Just for test purposes
let obj = {param1: 12, param2: "test"};

// Actual solution
let result = Object.keys(obj).reduce((prev, key, i) => (
  `${prev}${i!==0?'&':''}${key}=${obj[key]}`
), '');

// Run the snippet to show what happens!
console.log(result);


4

चूंकि मैंने एक पुनरावर्ती कार्य के बारे में इतना बड़ा सौदा किया है, यहां मेरा अपना संस्करण है।

function objectParametize(obj, delimeter, q) {
    var str = new Array();
    if (!delimeter) delimeter = '&';
    for (var key in obj) {
        switch (typeof obj[key]) {
            case 'string':
            case 'number':
                str[str.length] = key + '=' + obj[key];
            break;
            case 'object':
                str[str.length] = objectParametize(obj[key], delimeter);
        }
    }
    return (q === true ? '?' : '') + str.join(delimeter);
}

http://jsfiddle.net/userdude/Kk3Lz/2/


3
बस कुछ यादृच्छिक विचारों (ए) []को प्राथमिकता दी जाती है new Array()(बी) आप delimiter = delimiter || '&';तर्क डिफ़ॉल्ट के लिए उपयोग कर सकते हैं (और आपने इसे गलत लिखा है) (ग) for ( in )सभी ज्वलनशील गुणों पर पुनरावृति करेंगे, जिसमें प्रोटोटाइप श्रृंखला पर चीजें शामिल हैं (इसके लिए obj.hasOwnProperty()बचाव) (d) typeofइस बारे में झूठ बोल सकते हैं कि चीजें क्या हैं, उदाहरण के लिए कुछ संख्याएँ हो सकती हैं Objectयदि Number()कंस्ट्रक्टर (ई) के साथ सदस्यों को जोड़ने के लिए Arrayएक push()विधि है (एफ) की तुलना trueबेमानी है। मैं एक नाईटी कमीने हूँ लेकिन आप प्रतिक्रिया चाहते थे! :)
एलेक्स

1
... और अगर आप क्रॉकफ़ोर्ड की बात करें तो सब कुछ सही है, आपको स्विच के मामलों को कम नहीं होने देना चाहिए। मैं हालांकि उस पर उससे असहमत हूं। : डी
एलेक्स

@alex - मैं इसकी सराहना करता हूं। a) मेरे पास पहले था, देर हो चुकी थी और मुझे नींद आ रही थी; बी) निश्चित नहीं है कि सुधार क्या है, दूसरा भी नींद से वंचित पल था; ग) मैं सोच रहा था कि आपने क्यों इस्तेमाल किया hasOwnProperty(); घ) यह निश्चित रूप से सच है और एक अच्छी बात है; ई) मैंने कभी भी उपयोग push()या pop()विधियों के लिए उपयोग नहीं किया है ; च) breakया नहीं break, यह सवाल है। आपके विस्तृत इनपुट के लिए धन्यवाद। :)
जारेड फरिश

4

आपकी क्वेरी में सरणी होने पर एक उपयोगी कोड:

var queryString = Object.keys(query).map(key => {
    if (query[key].constructor === Array) {
        var theArrSerialized = ''
        for (let singleArrIndex of query[key]) {
            theArrSerialized = theArrSerialized + key + '[]=' + singleArrIndex + '&'
        }
        return theArrSerialized
    }
    else {
        return key + '=' + query[key] + '&'
    }
}
).join('');
console.log('?' + queryString)

4

यदि आप NodeJS 13.1 या श्रेष्ठ का उपयोग कर रहे हैं, तो आप क्वेरी स्ट्रिंग को पार्स करने के लिए देशी क्वेरिस्ट्रिंग मॉड्यूल का उपयोग कर सकते हैं।

const qs = require('querystring');
let str = qs.stringify(obj)

3
var str = '';

for( var name in obj ) {
    str += (name + '=' + obj[name] + '&');
}

str = str.slice(0,-1);

इसे एक शॉट दें।

उदाहरण: http://jsfiddle.net/T2UWT/


1
@ जारेड: लूप की तुलना में कम कुशल।
user113716

@Jared: Qs और As के नीचे उपयोगकर्ता नाम की आवश्यकता नहीं है। सूचनाएं स्वचालित हैं।
user113716

"कम प्रदर्शन करने वाला"? यदि मैं एक मनमानी वस्तु में गुजरता हूं, और चाहता हूं कि एक जीईटी स्ट्रिंग लौटा दी जाए, तो प्रदर्शन का इससे क्या लेना-देना है?
जेरेड फरिश

@ जय: मुझे क्षमा करें, लेकिन शायद मैं आपका अर्थ नहीं समझ पा रहा हूं। यदि आप लूप के बजाय पुनरावर्ती फ़ंक्शन कॉल का उपयोग करने का सुझाव दे रहे हैं, तो मैं काफी निश्चित हूं कि पुनरावर्ती कार्य लूप की तुलना में अधिक धीमी गति से प्रदर्शन करेंगे। क्या मैंने आपकी बात को गलत समझा है?
user113716

1
खैर, मुझे नहीं पता कि मुझे लगता है। यदि कोई ऐसा कार्य होता है, जो आप उसे एक वस्तु भेजते हैं और उस वस्तु के स्ट्रिंग-कॉन्सेटिव जीईटी-योग्य संस्करण को आउटपुट करते हैं, तो मुझे नहीं लगता कि एक लूप हमेशा इनपुट से निपटेगा। बेशक, एक एकल-स्तरीय लूप हमेशा बहु-स्तरीय पुनरावृत्ति को "बेहतर" करेगा, लेकिन एक-स्तरीय लूप भी बहु-स्तरीय ऑब्जेक्ट, IMO को संभाल नहीं पाएगा।
जेरेड फरिश जूल

3

आप jQuery की paramविधि का उपयोग कर सकते हैं :

var obj = {
  param1: 'something',
  param2: 'somethingelse',
  param3: 'another'
}
obj['param4'] = 'yetanother';
var str = jQuery.param(obj);
alert(str);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


3
new URLSearchParams({hello: 'world', foo: 'bar' }).toString()

काम करने लगता है। की कोई जरूरत नहीं encodeURIComponent। आउटपुटhello=world&foo=bar


1
यह मेरे द्वारा पोस्ट की गई एक डुप्लिकेट उत्तर है।
jfunk

2

यदि आपको एक पुनरावर्ती फ़ंक्शन की आवश्यकता है जो दिए गए ऑब्जेक्ट के आधार पर उचित URL पैरामीटर का उत्पादन करेगा, तो मेरा कॉफी-स्क्रिप्ट एक आज़माएं।

@toParams = (params) ->
    pairs = []
    do proc = (object=params, prefix=null) ->
      for own key, value of object
        if value instanceof Array
          for el, i in value
            proc(el, if prefix? then "#{prefix}[#{key}][]" else "#{key}[]")
        else if value instanceof Object
          if prefix?
            prefix += "[#{key}]"
          else
            prefix = key
          proc(value, prefix)
        else
          pairs.push(if prefix? then "#{prefix}[#{key}]=#{value}" else "#{key}=#{value}")
    pairs.join('&')

या जावास्क्रिप्ट संकलित ...

toParams = function(params) {
  var pairs, proc;
  pairs = [];
  (proc = function(object, prefix) {
    var el, i, key, value, _results;
    if (object == null) object = params;
    if (prefix == null) prefix = null;
    _results = [];
    for (key in object) {
      if (!__hasProp.call(object, key)) continue;
      value = object[key];
      if (value instanceof Array) {
        _results.push((function() {
          var _len, _results2;
          _results2 = [];
          for (i = 0, _len = value.length; i < _len; i++) {
            el = value[i];
            _results2.push(proc(el, prefix != null ? "" + prefix + "[" + key + "][]" : "" + key + "[]"));
          }
          return _results2;
        })());
      } else if (value instanceof Object) {
        if (prefix != null) {
          prefix += "[" + key + "]";
        } else {
          prefix = key;
        }
        _results.push(proc(value, prefix));
      } else {
        _results.push(pairs.push(prefix != null ? "" + prefix + "[" + key + "]=" + value : "" + key + "=" + value));
      }
    }
    return _results;
  })();
  return pairs.join('&');
};

इस तरह तार का निर्माण होगा:

toParams({a: 'one', b: 'two', c: {x: 'eight', y: ['g','h','j'], z: {asdf: 'fdsa'}}})

"a=one&b=two&c[x]=eight&c[y][0]=g&c[y][1]=h&c[y][2]=j&c[y][z][asdf]=fdsa"

मुझे लगता है कि मैं इसे दीवार पर लटका दूँगा
पाई 6k

2

एक कार्यात्मक दृष्टिकोण।

var kvToParam = R.mapObjIndexed((val, key) => {
  return '&' + key + '=' + encodeURIComponent(val);
});

var objToParams = R.compose(
  R.replace(/^&/, '?'),
  R.join(''),
  R.values,
  kvToParam
);

var o = {
  username: 'sloughfeg9',
  password: 'traveller'
};

console.log(objToParams(o));
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.22.1/ramda.min.js"></script>



0

यह विधि ऑब्जेक्ट पदानुक्रम में उतरने के लिए और रेल स्टाइल पार्म्स उत्पन्न करने के लिए पुनरावृत्ति का उपयोग करती है जो एम्बेडेड हैश के रूप में व्याख्या करता है। objToParams अंत में एक अतिरिक्त एम्परसेंड के साथ एक क्वेरी स्ट्रिंग उत्पन्न करता है, और objToQuery अंतिम एम्परसेन्ड को हटा देता है।

 function objToQuery(obj){
  let str = objToParams(obj,'');
  return str.slice(0, str.length);
}
function   objToParams(obj, subobj){
  let str = "";

   for (let key in obj) {
     if(typeof(obj[key]) === 'object') {
       if(subobj){
         str += objToParams(obj[key], `${subobj}[${key}]`);
       } else {
         str += objToParams(obj[key], `[${key}]`);
       }

     } else {
       if(subobj){
         str += `${key}${subobj}=${obj[key]}&`;
       }else{
         str += `${key}=${obj[key]}&`;
       }
     }
   }
   return str;
 }


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.