2008-11-25 10 views
96

Zastanawiasz się, czy jest coś wbudowanego w JavaScript, które może pobrać formularz i zwrócić parametry zapytania, np .: "var1 = wartość & var2 = wartość2 & arr [] = foo & arr [] = bar ... "Jak zbudować ciąg zapytania z JavaScriptem

Zastanawiam się nad tym od lat.

+1

FYI: http://phpjs.org/functions/http_build_query/ –

+1

możliwe duplikat [Utwórz parametrów kwerendy w JavaScript] (http://stackoverflow.com/questions/ 111529/create-query-parameters-in-javascript) – Moes

Odpowiedz

6

Próbowałem szukać odpowiedzi na to pytanie jakiś czas temu, ale skończyło się na pisanie własnych funkcji, która pobiera wartości z formularza ..

to nie jest idealne, ale to pasuje do moich potrzeb.

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 zwraca mapowanie (klucz -> wartość) parametrów. dane wejściowe to element formularza (element DOM)

Nie obsługuje pól, które umożliwiają wielokrotny wybór.

+0

Mam ten sam kod: D To bije w tym gigantyczne ramy. –

+25

Czy to tylko ja lub czy to w ogóle nie odpowiada na pytanie? Pytał o ciąg zapytania, a nie tablicę odwzorowaną. –

+0

@JakeWilson Tak, ta odpowiedź tylko w połowie odpowiada na pytanie. Tablica nadal musi dostać się do formatu ciągu zapytania. –

3

Nie jestem do końca pewny siebie, przypominam, że widzę, że jQuery zrobił to w pewnym stopniu, ale w ogóle nie obsługuje rekordów hierarchicznych, nie mówiąc już o przyjaznym php.

Jedną rzeczą, którą wiem na pewno, jest to, że budując adresy URL i umieszczając produkt w domenie, nie używaj do tego celu tylko kleju, lub otworzysz się na poręczny łamacz stron.

Na przykład, niektóre programy reklamowe zawieszają ciąg znaków wersji niezależnie od tego, czy działa Flash. Jest to w porządku, gdy jego adobes generyczny prosty ciąg, ale jest to bardzo naiwny i wysadza w zakłopotanie dla ludzi, którzy zainstalowali Gnasha, ponieważ ciąg znaków gnash'es zawiera pełne licencje na prawa autorskie GPL, wraz z adresami URL i < znaczniki href >. Korzystanie z tego w generatorze reklam z ciągami klejowymi powoduje, że strona zaczyna otwierać się i pojawia się niewyważony kod HTML w domenie.

Morał z tej historii:

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

Nie:

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

Google muszą nauczyć się tej sztuczki. Próbowałem zgłosić problem, wydaje się, że nie obchodzi ich to.

+0

Włączone. Document.write jest * tak * 1995, tak czy inaczej. –

10

Nie, nie sądzę, że norma JavaScript został zbudowany w, ale Prototype JS ma taką funkcję (na pewno większość innych ram JS mają zbyt, ale ja ich nie znam), nazywają go serialize.

Mogę polecić prototyp JS, działa całkiem nieźle. Jedyną wadą, którą zauważyłem, jest rozmiar (kilkaset kb) i zasięg (mnóstwo kodu dla ajax, dom itp.). Tak więc, jeśli chcesz tylko serializatora formularzy, jest to przesada, a mówiąc ściśle, jeśli chcesz tylko, aby była to funkcjonalność Ajax (która jest głównie tym, czego używałam), jest to przesada. O ile nie jesteś ostrożny, możesz zauważyć, że robi trochę zbyt wiele "magii" (jak rozszerzenie każdego elementu dom, który dotyka prototypowymi funkcjami JS tylko po to, aby znaleźć elementy), co spowalnia w ekstremalnych przypadkach.

+0

Zastanawiasz się, czy jest coś wbudowanego. Wygląda na to, że powinno być. Nienawidzę prototypu, ale nie utrzymuję tego przeciwko tobie :) –

+0

Gdy JavaScript został zaprojektowany, Ajax nie został jeszcze odkryty, dlatego parsowanie formularza tylko po to, aby uzyskać querystring (który sam byłby kreatyny po przesłaniu) prawdopodobnie nie zrobiło wiele sens. Dzisiaj to robi, ciężko ... Btw, w porównaniu do script.aculo.us, prototyp jest * miły *. :) –

3

Jak mówi Stein, można użyć prototypowej biblioteki javascript z http://www.prototypejs.org. Dołączenie JS i jest bardzo proste, $('formName').serialize() zwróci to, co chcesz!

6

Jeśli nie chcesz korzystać z biblioteki, powinno to dotyczyć większości/wszystkich tych samych typów elementów formularza.

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('&'); 
} 
+0

Dzięki! Miałem właśnie ten sam problem, co oryginalny plakat, a twoja funkcja była dokładnie tym, czego potrzebowałem. – dagw

5

Nie potrzebujesz do tego formularza z prototypem. Wystarczy użyć Object.toQueryString function:

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' 
51

nie bezpośrednio odpowiedzieć na to pytanie, ale tutaj jest rodzajowy funkcja, która utworzy adres URL, który zawiera parametry ciągu zapytania. Parametry (nazwy i wartości) są bezpiecznie chronione przed wprowadzeniem do adresu URL.

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

Czy istnieje jakaś wbudowana funkcja podobna do tej w jednym z popularnych frameworków javascript takich jak jquery, mootools, etc ...? – Samuel

+0

Bardziej wytrzymałe natywne rozwiązanie JavaScript jest na http://stackoverflow.com/a/1714899/1269037 –

+0

Weirdest wdrożenia kiedykolwiek, dlaczego musisz zainicjować 'nowy Array', podczas gdy faktycznie używasz go jako obiekt? o, O –

103

Jeśli używasz jQuery może chcesz sprawdzić jQuery.param()http://api.jquery.com/jQuery.param/

Przykład:

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

To jest właściwie poprawna odpowiedź! Łańcuch zapytania dla formularza to '$ .param ($ ('# myform'). SerializeArray())'. – Jesse

+7

@Jesse, to byłby ten sam wynik co: '$ ('# myform'). Serialize()' – cleaver

+65

'jQuery! == JavaScript' – gphilip

21

z jQuery można to zrobić przez $.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" 
0

Czy jest prawdopodobnie za późno, aby odpowiedzieć na twoje pytanie.
Miałem to samo pytanie i nie lubiłem dodawać ciągów do utworzenia adresu URL. Zacząłem więc wyjaśniać $ .param jako techhouse.
Znalazłem także bibliotekę URI.js, która z łatwością tworzy dla Ciebie adresy URL. Istnieje kilka przykładów, które pomogą Ci: URI.js Documentation.
Oto jeden z nich:

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"]);` 
100

Bez jQuery

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('&'); 
+4

Najlepsze rozwiązanie, jakie widziałem - bardzo czyste i zwięzłe. Jednak kilka zastrzeżeń. 1) w .map(), zarówno k jak i params [k] powinny być zakodowane, np. encodeURIComponent (k) i encodeURIComponent (parametry [k]). 2) Możesz mieć więcej niż jedno wystąpienie nazwanego parametru w ciągu zapytania. Jeśli chcesz taką możliwość, będziesz musiał użyć tablicy zamiast obiektu (większość aplikacji tego nie chce lub nie potrzebuje). – user1738579

+5

3) Nie wszystkie przeglądarki obsługują składnię funkcji strzałek (wymaga to ES5). Jeśli chcesz obsługiwać wszystkie przeglądarki (i kodować części), zastąp powyższą .map() opcją .map (function (k) {return encodeURIComponent (k) + '=' + encodeURIComponent (parametry [k]);}) – user1738579

+1

Piękny. Naprawdę piękny. –

5

querystring może pomóc.

Więc można

const querystring = require('querystring') 

url += '?' + querystring.stringify(parameters)