Javascript ile sorgu dizesi oluşturma


Yanıtlar:


-24

Bir süre önce bu soruya bir cevap aramaya çalıştım, ancak formdan değerleri alan kendi fonksiyonumu yazdım.

mükemmel değil ama ihtiyaçlarımı karşılıyor.

function form_params( form )
{
    var params = new Array()
    var length = form.elements.length
    for( var i = 0; i < length; i++ )
    {
        element = form.elements[i]

        if(element.tagName == 'TEXTAREA' )
        {
            params[element.name] = element.value
        }
        else if( element.tagName == 'INPUT' )
        {
            if( element.type == 'text' || element.type == 'hidden' || element.type == 'password')
            {
                params[element.name] = element.value
            }
            else if( element.type == 'radio' && element.checked )
            {
                if( !element.value )
                    params[element.name] = "on"
                else
                    params[element.name] = element.value

            }
            else if( element.type == 'checkbox' && element.checked )
            {
                if( !element.value )
                    params[element.name] = "on"
                else
                    params[element.name] = element.value
            }
        }
    }
    return params;
}

form_params parametrelerin (anahtar -> değer) eşlemesini döndürür. girdi form öğesidir (DOM Öğesi)

Çoklu seçime izin veren alanları işlemez.


44
Sadece ben miyim yoksa bu soruya hiç cevap vermiyor mu? Eşlenmiş bir dizi değil, bir sorgu dizesi istiyordu.
Jake Wilson

2
@JakeWilson Evet, bu cevap soruyu sadece yarısı cevaplıyor. Dizinin yine de bir sorgu dizesi biçimine girmesi gerekir.
Hutch Moore

9
wow O zamanlar JS'de bir çaylak olmalıydım. new Array()Bir sözlüğü başlatmak için kullanma . Ama sonra tekrar, kod bugünlerde yazacağım bok bazı daha çok daha temiz görünüyor!
hasen

2
@hasen belki de bu cevabı düzenlemeyi düşünürsünüz, yoksa silebilirsiniz? Her kaydırdığımda gittikçe daha fazla aşağı oyu var = -D (Olumlu bir oranın olduğu zamanı bile hatırlıyorum ...)
Klesun

1
@ArturKlesun evet, hayır. Umurumda değil. Soruyu soran kişiden bu yanıtı kabul etmesini istemeyi deneyebilirsiniz.
hasen

220

2k20 güncellemesi: Josh'un çözümünü URLSearchParams.toString () ile kullanın .

Eski cevap:


JQuery olmadan

var params = {
    parameter1: 'value_1',
    parameter2: 'value 2',
    parameter3: 'value&3' 
};

var esc = encodeURIComponent;
var query = Object.keys(params)
    .map(k => esc(k) + '=' + esc(params[k]))
    .join('&');

ES5 gerektiren ok işlevi sözdizimini desteklemeyen tarayıcılar için .map...satırı

    .map(function(k) {return esc(k) + '=' + esc(params[k]);})

8
Şimdiye kadar gördüğüm en iyi çözüm - çok temiz ve özlü. Birkaç uyarı olsa da. 1) .map () içinde, hem k hem de parametreler [k] kodlanmalıdır, örneğin encodeURIComponent (k) ve encodeURIComponent (params [k]). 2) Bir sorgu dizesinde adlandırılmış bir parametrenin birden fazla örneğine sahip olmanıza izin verilir. Bu özelliği istiyorsanız, nesne yerine bir dizi kullanmanız gerekir (çoğu uygulama bunu istemez veya buna ihtiyaç duymaz).
John Deighan

9
3) Tüm tarayıcılar ok işlevi sözdizimini desteklemez (ES5 gerektirir). Tüm tarayıcıları desteklemek (ve parçaları kodlamak) istiyorsanız, yukarıdaki .map () yerine .map (function (k) {return encodeURIComponent (k) + '=' + encodeURIComponent (params [k]);})
John Deighan

1
Güzel. Gerçekten güzel.
Mikko Ohtamaa

9
"yeterli jquery"
Eugene Pankov

1
@ user1738579 Cevabı, ES5 dışı örneğinizi de içerecek şekilde düzenledim.
Taylor Edmiston

134

JQuery kullanıyorsanız http://api.jquery.com/jQuery.param/ adresine göz atmak isteyebilirsiniz.jQuery.param()

Misal:

var params = {
    parameter1: 'value1',
    parameter2: 'value2',
    parameter3: 'value3' 
};
var query = $.param(params);
document.write(query);

13
Bu aslında doğru cevap! Bir formun sorgu dizesi $.param($('#myform').serializeArray()).
Jesse

7
@Jesse, bu şu şekilde sonuçlanır:$('#myform').serialize()
cleaver

95
jQuery !== JavaScript
gphilip

14
@gphilip Bu yüzden "jQuery kullanıyorsanız ..." ile yanıt vermeye başladım. Aksi takdirde vanilya JS'de uygulamak istiyorsanız, jQuery.param()burada uygulanmasını inceleyebilirsiniz github.com/jquery/jquery/blob/master/src/serialize.js :)
Klemen Tušar

2
Cevabımın aksine bu gibi yuvalanmış nesneleri desteklersomeStr=value1&someObj[a]=5&someObj[b]=6&someArr[]=1&someArr[]=2
Klesun

113

URLSearchParams API'sı tüm modern tarayıcılarda kullanılabilir. Örneğin:

const params = new URLSearchParams({
  var1: "value",
  var2: "value2",
  arr: "foo",
});
console.log(params.toString());
//Prints "var1=value&var2=value2&arr=foo"


3
Burada en iyi cevap imo. Sadece eklemek için, params.append(key, value)daha karmaşık senaryolara yeni arama parametreleri eklemek için daha sonra yapabilirsiniz .
Mingwei Zhang

4
x=null&y=undefined
Undefined

2
Ayrıca, zaten bir URL nesneniz varsa (örneğin const url = new URL("https://stackoverflow.com")), sorgu dizelerini url.search = new URLSearchParams({foo: "bar"})veyaurl.searchParams.append("foo", "bar")
Miguel Pynto

TS'nin düz bir nesne kullanma konusunda uyaracağını unutmayın, ancak yine de iyi çalışıyor
Vadorequest

@pomber Tanımsız öğeleri filtrelemeye ilişkin iyi fikirler var mı?
Dan Gayle

53

Bu doğrudan sorunuzu cevaplamıyor, ancak burada sorgu dizesi parametreleri içeren bir URL oluşturacak genel bir işlev var. Parametreler (adlar ve değerler) bir URL'ye dahil edilmek üzere güvenli bir şekilde çıkar.

function buildUrl(url, parameters){
  var qs = "";
  for(var key in parameters) {
    var value = parameters[key];
    qs += encodeURIComponent(key) + "=" + encodeURIComponent(value) + "&";
  }
  if (qs.length > 0){
    qs = qs.substring(0, qs.length-1); //chop off last "&"
    url = url + "?" + qs;
  }
  return url;
}

// example:
var url = "http://example.com/";

var parameters = {
  name: "George Washington",
  dob: "17320222"
};

console.log(buildUrl(url, parameters));
// => http://www.example.com/?name=George%20Washington&dob=17320222

1
Jquery, mootools, vb. Gibi popüler javascript çerçevelerinden birinde buna benzer yerleşik bir işlev var mı?
Samuel

Daha sağlam bir yerel JavaScript çözümü stackoverflow.com/a/1714899/1269037
Dan Dascalescu

Şimdiye kadarki en garip uygulama, neden new Arraybir nesne olarak kullanırken bir süre başlatmanız gerekiyor ? o, O
Umut Şirin

@UmutSirin Lol evet O sırada Javascript hakkında çok şey bilmiyordum. xD Ben bir PHP dizi gibi davranıyordum düşünüyorum. İsterseniz refactor çekinmeyin.
Michael

@Michael Haha, evet. Az önce bir düzenleme gönderdim. Cevap için teşekkür ederim!
Umut Şirin

22

JQuery ile bunu yapabilirsiniz $.param

$.param({ action: 'ship', order_id: 123, fees: ['f1', 'f2'], 'label': 'a demo' })

// -> "action=ship&order_id=123&fees%5B%5D=f1&fees%5B%5D=f2&label=a+demo"

17

ES2017 (ES8)

Object.entries()Nesnenin [key, value]çiftlerinden oluşan bir dizi döndüren faydalanılması . Örneğin, {a: 1, b: 2}geri dönecekti [['a', 1], ['b', 2]]. Yalnızca IE tarafından desteklenmez (ve olmayacak).

Kod:

const buildURLQuery = obj =>
      Object.entries(obj)
            .map(pair => pair.map(encodeURIComponent).join('='))
            .join('&');

Misal:

buildURLQuery({name: 'John', gender: 'male'});

Sonuç:

"name=John&gender=male"


10

Hayır, standart JavaScript'in yerleşik olduğunu düşünmüyorum, ancak Prototip JS'nin bu işlevi var (elbette diğer çoğu JS çerçevesinin de var, ama onları bilmiyorum), seri hale çağırıyorlar .

Prototip JS öneriyoruz, oldukça iyi çalışıyor. Tek dezavantajı gerçekten boyutu (birkaç yüz kb) ve kapsamı (ajax, dom, vb için kod bir sürü) fark ettim. Bu nedenle, sadece bir form serileştiricisi istiyorsanız, bu aşırıya kaçar ve kesinlikle Ajax işlevselliği istiyorsanız (esas olarak bunun için kullandığım şeydir) aşırıya kaçar. Dikkatli olmadıkça, biraz fazla "büyü" yaptığını (sadece öğeleri bulmak için Prototip JS işlevleriyle dokunduğu her dom öğesini genişletmek gibi) aşırı durumlarda yavaşlattığını görebilirsiniz.


Sadece yerleşik bir şey olup olmadığını merak ediyorum. Olması gerektiği gibi görünüyor. Prototipten nefret ediyorum, ama sana karşı

JavaScript tasarlandığında, Ajax henüz keşfedilmedi, bu nedenle sadece sorgu dizesini almak için bir form ayrıştırıldı (gönderildiğinde kendini yaratacaktır) muhtemelen pek mantıklı değildi. Bugün, zor ... Btw, script.aculo.us ile karşılaştırıldığında, prototip güzel . :)
Stein G. Strindhaug


6

Bir kitaplık kullanmak istemiyorsanız, bu, aynı form öğesi türlerinin çoğunu / tümünü kapsamalıdır.

function serialize(form) {
  if (!form || !form.elements) return;

  var serial = [], i, j, first;
  var add = function (name, value) {
    serial.push(encodeURIComponent(name) + '=' + encodeURIComponent(value));
  }

  var elems = form.elements;
  for (i = 0; i < elems.length; i += 1, first = false) {
    if (elems[i].name.length > 0) { /* don't include unnamed elements */
      switch (elems[i].type) {
        case 'select-one': first = true;
        case 'select-multiple':
          for (j = 0; j < elems[i].options.length; j += 1)
            if (elems[i].options[j].selected) {
              add(elems[i].name, elems[i].options[j].value);
              if (first) break; /* stop searching for select-one */
            }
          break;
        case 'checkbox':
        case 'radio': if (!elems[i].checked) break; /* else continue */
        default: add(elems[i].name, elems[i].value); break;
      }
    }
  }

  return serial.join('&');
}

Teşekkürler! Sadece orijinal posterle aynı problemle karşı karşıyaydım ve fonksiyonunuz tam olarak ihtiyacım olan şeydi.
dagw

4

Prototip ile bunu yapmak için aslında bir forma ihtiyacınız yoktur. Sadece Object.toQueryString işlevini kullanın :

Object.toQueryString({ action: 'ship', order_id: 123, fees: ['f1', 'f2'], 'label': 'a demo' })

// -> 'action=ship&order_id=123&fees=f1&fees=f2&label=a%20demo'

4
Kabul edersiniz, yaklaşık 10 yıl önce cevap verdiniz, ancak bu kod artık kullanımdan kaldırıldı.
SEOF

4

Sen ile günümüzde bunu yapabilir FormDatave URLSearchParamsherhangi bir şey üzerinde döngü gerek kalmadan.

const formData = new FormData(form);
const searchParams = new URLSearchParams(formData);
const queryString = searchParams.toString();

Ancak eski tarayıcıların çoklu doldurmaya ihtiyacı olacaktır.


3

Tamamen kendimden emin değilim, jQuery'nin bunu bir ölçüde yaptığını hatırlıyorum, ancak php dostu bir şekilde, hiyerarşik kayıtları hiç tutmuyor.

Kesin olarak bildiğim bir şey, URL'ler oluştururken ve ürünü dom'a yapıştırırken, bunu yapmak için sadece string-glue kullanmayın, ya da kendinizi kullanışlı bir sayfa kırıcıya açacaksınız.

Örneğin, bazı reklamcılık yazılımları sürüm dizesini flash'ınızı çalıştırandan satırlar. Bu, adobes jenerik basit dize olduğunda iyidir, ancak bu çok naiftir ve gnash'i yükleyen insanlar için gnash'lerin sürüm dizesi URL'lerle tamamlanmış tam bir GPL telif hakkı lisansları içerdiğinden, utanç verici bir karmaşaya patlar. ve <a href> etiketleri. Bunu string-glue reklamveren jeneratörünüzde kullanmak, sayfanın açılmasına ve dom'de dengesiz HTML'ye sahip olmasına neden olur.

Hikayenin ahlakı:

   var foo = document.createElement("elementnamehere"); 
   foo.attribute = allUserSpecifiedDataConsideredDangerousHere; 
   somenode.appendChild(foo); 

Değil:

   document.write("<elementnamehere attribute=\"" 
        + ilovebrokenwebsites 
        + "\">" 
        + stringdata 
        + "</elementnamehere>");

Google'ın bu numarayı öğrenmesi gerekiyor. Sorunu bildirmeye çalıştım, umursamıyorlar.


Kesinlikle doğru. Document.write olduğunu bu yüzden zaten, 1995.



2

Biraz gereksiz olabilir ama burada bazı cevaplar üzerine inşa bulundu en temiz yolu:

const params: {
   key1: 'value1',
   key2: 'value2',
   key3: 'value3',
}

const esc = encodeURIComponent;
const query = Object.keys(params)
  .map(k => esc(k) + '=' + esc(params[k]))
  .join('&');

return fetch('my-url', {
  method: 'POST',
  headers: {'Content-Type': 'application/x-www-form-urlencoded'},
  body: query,
})

Kaynak


1

Bu yanıtlar çok faydalıdır, ancak tam URL oluşturmanıza yardımcı olabilecek başka bir yanıt eklemek istiyorum. Bu üs concat size yardımcı olabilir url, path, hashve parameters.

var url = buildUrl('http://mywebsite.com', {
        path: 'about',
        hash: 'contact',
        queryParams: {
            'var1': 'value',
            'var2': 'value2',
            'arr[]' : 'foo'
        }
    });
    console.log(url);

Https://www.npmjs.com/package/build-url npm adresinden indirebilirsiniz.

Demo:

;(function () {
  'use strict';

  var root = this;
  var previousBuildUrl = root.buildUrl;

  var buildUrl = function (url, options) {
    var queryString = [];
    var key;
    var builtUrl;
    var caseChange; 
    
    // 'lowerCase' parameter default = false,  
    if (options && options.lowerCase) {
        caseChange = !!options.lowerCase;
    } else {
        caseChange = false;
    }

    if (url === null) {
      builtUrl = '';
    } else if (typeof(url) === 'object') {
      builtUrl = '';
      options = url;
    } else {
      builtUrl = url;
    }

    if(builtUrl && builtUrl[builtUrl.length - 1] === '/') {
      builtUrl = builtUrl.slice(0, -1);
    } 

    if (options) {
      if (options.path) {
          var localVar = String(options.path).trim(); 
          if (caseChange) {
            localVar = localVar.toLowerCase();
          }
          if (localVar.indexOf('/') === 0) {
              builtUrl += localVar;
          } else {
            builtUrl += '/' + localVar;
          }
      }

      if (options.queryParams) {
        for (key in options.queryParams) {
          if (options.queryParams.hasOwnProperty(key) && options.queryParams[key] !== void 0) {
            var encodedParam;
            if (options.disableCSV && Array.isArray(options.queryParams[key]) && options.queryParams[key].length) {
              for(var i = 0; i < options.queryParams[key].length; i++) {
                encodedParam = encodeURIComponent(String(options.queryParams[key][i]).trim());
                queryString.push(key + '=' + encodedParam);
              }
            } else {              
              if (caseChange) {
                encodedParam = encodeURIComponent(String(options.queryParams[key]).trim().toLowerCase());
              }
              else {
                encodedParam = encodeURIComponent(String(options.queryParams[key]).trim());
              }
              queryString.push(key + '=' + encodedParam);
            }
          }
        }
        builtUrl += '?' + queryString.join('&');
      }

      if (options.hash) {
        if(caseChange)
            builtUrl += '#' + String(options.hash).trim().toLowerCase();
        else
            builtUrl += '#' + String(options.hash).trim();
      }
    } 
    return builtUrl;
  };

  buildUrl.noConflict = function () {
    root.buildUrl = previousBuildUrl;
    return buildUrl;
  };

  if (typeof(exports) !== 'undefined') {
    if (typeof(module) !== 'undefined' && module.exports) {
      exports = module.exports = buildUrl;
    }
    exports.buildUrl = buildUrl;
  } else {
    root.buildUrl = buildUrl;
  }
}).call(this);


var url = buildUrl('http://mywebsite.com', {
		path: 'about',
		hash: 'contact',
		queryParams: {
			'var1': 'value',
			'var2': 'value2',
			'arr[]' : 'foo'
		}
	});
	console.log(url);


1

Bunun çok geç bir cevap olduğunu biliyorum ama çok iyi çalışıyor ...

var obj = {
a:"a",
b:"b"
}

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

not: object.entries anahtar döndürür, değer çiftleri

yukarıdaki satırdan çıkış a = a & b = b olacaktır

Umarım birine yardım eder.

Mutlu Kodlama ...


0

Muhtemelen sorunuza cevap vermek için çok geç.
Aynı soruyu sordum ve URL oluşturmak için dizeleri eklemeye devam etmek istemedim. Yani, ben $ .param kullanmaya başladı Techhouse açıkladı. URL'leri sizin için kolayca oluşturan
bir URI.js kütüphanesi de buldum . Size yardımcı olacak birkaç örnek vardır: URI.js Belgeleri .
İşte bunlardan biri:

var uri = new URI("?hello=world");
uri.setSearch("hello", "mars"); // returns the URI instance for chaining
// uri == "?hello=mars"

uri.setSearch({ foo: "bar", goodbye : ["world", "mars"] });
// uri == "?hello=mars&foo=bar&goodbye=world&goodbye=mars"

uri.setSearch("goodbye", "sun");
// uri == "?hello=mars&foo=bar&goodbye=sun"

// CAUTION: beware of arrays, the following are not quite the same
// If you're dealing with PHP, you probably want the latter…
uri.setSearch("foo", ["bar", "baz"]);
uri.setSearch("foo[]", ["bar", "baz"]);`

0

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

console.log(str)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.