2008-11-25 4 views
96

Einfach fragen, bauen, wenn es etwas, eingebaut in Javascript ist, dass ein Formular und gibt die Abfrageparameter übernehmen, zB: „var1 = Wert & var2 = Wert2 & arr [] = foo & arr [] = bar ...“Wie Query-String mit Javascript

ich habe dies seit Jahren fragen.

+1

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

+1

möglich Duplikat [Abfrageparameter in JavaScript erstellen] (http://stackoverflow.com/questions/ 111529/create-query-parameters-in-javascript) – Moes

Antwort

6

Ich habe versucht, vor einer Antwort auf diese Frage einige während zu suchen, aber ich beenden meine eigene Funktion zu schreiben auf, die die Werte aus dem Formular extrahiert ..

es ist nicht perfekt, aber sie paßt meine Bedürfnisse.

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 gibt eine (Schlüssel -> Wert) Abbildung der Parameter zurück. Die Eingabe ist das Formularelement (DOM-Element)

Es behandelt keine Felder, die Mehrfachauswahl zulassen.

+0

Ich habe den gleichen Code: D Es schlägt einschließlich einige riesige Rahmen. –

+25

Ist es nur ich oder beantwortet das die Frage überhaupt nicht? Er fragte nach einer Abfragezeichenfolge und nicht nach einem zugeordneten Array. –

+0

@JakeWilson Ja, diese Antwort beantwortet nur die Hälfte die Frage. Das Array muss immer noch in ein Abfragezeichenfolgenformat gelangen. –

3

Ich bin nicht ganz sicher, mich selbst, ich erinnere sehen jQuery tat es in ein Ausmaß, aber es behandelt nicht hierarchische Aufzeichnungen überhaupt, geschweige denn in einer PHP-freundlichen Art und Weise.

Eine Sache, die ich sicher weiß, ist beim Erstellen von URLs und das Produkt in das Dom stecken, nicht nur mit Bindfaden, oder Sie öffnen sich zu einem handlichen Seitenbrecher.

Zum Beispiel können bestimmte Werbesoftware in-Linien die String-Version von was auch immer läuft Ihre Flash. Das ist in Ordnung, wenn seine adobes generic einfacher String, aber aber das ist sehr naiv, und bläst in einer peinlichen Chaos für Personen die Gnash installiert haben, als gnash'es Version String geschieht mit URLs zu einer ausgewachsenen GPL Copyright-Lizenzen, komplett enthält und < a href > Tags. Wenn Sie dies in Ihrem Werbetreibenden-Generator für Zeichenketten verwenden, führt dies dazu, dass die Seite geöffnet wird und im HTML-Code unausgeglichenes HTML angezeigt wird.

Die Moral der Geschichte:

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

Nicht:

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

Google diesen Trick lernen müssen. Ich habe versucht, das Problem zu melden, es scheint ihnen egal zu sein. Kein

+0

Direkt rechts. Document.write ist sowieso * so * 1995. –

10

, ich glaube nicht, Standard JavaScript, dass in gebaut hat, aber Prototype JS hat diese Funktion (sicherlich die meisten anderen JS-Frameworks zu haben, aber ich kenne sie nicht), sie nennen es serialize.

Ich kann Prototype JS empfehlen, es ganz in Ordnung funktioniert. Der einzige Nachteil, ich habe es wirklich bemerkt, es ist die Größe (ein paar hundert kb) und Umfang (viel Code für Ajax, Dom, etc.). Also, wenn Sie nur einen Formular-Serialisierer wollen, ist es Overkill, und streng genommen, wenn Sie nur wollen, dass es Ajax-Funktionalität ist (was hauptsächlich ist, wofür ich es benutzt habe), ist es übertrieben. Wenn Sie nicht vorsichtig sind, stellen Sie vielleicht fest, dass es ein wenig zu viel "Magie" ist (wie jedes dom-Element, das es mit den Funktionen von Prototype JS berührt, nur um Elemente zu finden), was es im Extremfall verlangsamt.

+0

Ich frage mich nur, ob etwas eingebaut ist. Scheint so, als müsste es sein. Ich hasse Prototyp, aber ich halte das nicht gegen dich :) –

+0

Als JavaScript entworfen wurde, wurde Ajax noch nicht entdeckt, daher Parsing ein Formular, nur um den Querystring zu bekommen (dass es created selbst wenn eingereicht) wahrscheinlich nicht viel Sinn. Heute tut es das, hart ... Übrigens, im Vergleich zu script.aculo.us ist der Prototyp * nett *. :) –

3

Wie Stein sagt, können Sie die Prototyp-Javascript-Bibliothek von http://www.prototypejs.org verwenden. Fügen Sie die JS und es ist sehr einfach dann, $('formName').serialize() zurückkehren wird, was Sie wollen!

6

Wenn Sie keine Bibliothek verwenden möchten, sollte dies die meisten/alle der gleichen Formularelementtypen abdecken.

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

Danke! Ich hatte gerade das gleiche Problem wie das Original-Poster und Ihre Funktion war genau das, was ich brauchte. – dagw

5

Sie benötigen eigentlich kein Formular, um dies mit Prototype zu tun. Nur Object.toQueryString function verwenden:

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

Dies gilt nicht direkt Ihre Frage zu beantworten, aber hier ist eine generische Funktion, die eine URL erstellen wird, die Query-String-Parameter enthält. Die Parameter (Namen und Werte) werden sicher für die Aufnahme in eine URL maskiert.

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

Gibt es eine eingebaute Funktion ähnlich zu dieser in einem der populären JavaScript-Frameworks wie jquery, mootools, etc ...? – Samuel

+0

Eine robustere native JavaScript-Lösung finden Sie unter http://stackoverflow.com/a/1714899/1269037 –

+0

Die seltsamste Implementierung überhaupt, warum müssen Sie ein 'neues Array' initialisieren, während Sie es tatsächlich als Objekt verwenden? o, O –

103

Wenn Sie jQuery verwenden Sie könnten jQuery.param()http://api.jquery.com/jQuery.param/

Beispiel prüfen wollen:

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

Das ist eigentlich die richtige Antwort! Die Abfragezeichenfolge für ein Formular lautet '$ .param ($ ('# myform'). SerializeArray())'. – Jesse

+7

@Jesse, das wäre das gleiche Ergebnis wie: '$ ('# myform'). Serialize()' – cleaver

+65

'jQuery! == JavaScript' – gphilip

21

Mit jQuery können Sie dies tun, indem $.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

Ist ist wahrscheinlich zu spät, um Ihre Frage zu beantworten.
Ich hatte die gleiche Frage und ich wollte nicht weiterhin Zeichenfolgen anhängen, um eine URL zu erstellen. Also, ich begann mit $ .param als techhouse erklärt.
Ich fand auch eine URI.js Bibliothek, die leicht die URLs für Sie erstellt. Es gibt mehrere Beispiele, die Ihnen helfen werden: URI.js Documentation.
Hier ist einer von ihnen:

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

Ohne 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

Beste Lösung, die ich bisher gesehen habe - sehr sauber und prägnant. Ein paar Vorbehalte. 1) in der .map() sollten sowohl k als auch params [k] codiert sein, z.B. encodeURIComponent (k) und encodeURIComponent (params [k]). 2) Sie dürfen mehr als eine Instanz eines benannten Parameters in einer Abfragezeichenfolge haben. Wenn Sie diese Fähigkeit möchten, müssen Sie ein Array anstelle eines Objekts verwenden (die meisten Anwendungen wollen oder brauchen das nicht). – user1738579

+5

3) Nicht alle Browser unterstützen die Pfeilfunktionssyntax (für die ES5 erforderlich ist). Wenn Sie alle Browser unterstützen (und die Teile codieren möchten), ersetzen Sie die obige .map() durch .map (function (k) {return encodeURIComponent (k) + '=' + encodeURIComponent (params [k]);}) – user1738579

+1

Schön. Wahrhaft schön. –

5

querystring helfen kann.

So können Sie

const querystring = require('querystring') 

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