Zastanawiam się tylko, czy w Javascript jest coś wbudowanego, które może przyjąć formularz i zwrócić parametry zapytania, np .: "var1=value&var2=value2&arr[]=foo&arr[]=bar..."
Zastanawiałem się nad tym od lat.
Zastanawiam się tylko, czy w Javascript jest coś wbudowanego, które może przyjąć formularz i zwrócić parametry zapytania, np .: "var1=value&var2=value2&arr[]=foo&arr[]=bar..."
Zastanawiałem się nad tym od lat.
Odpowiedzi:
Jakiś czas temu próbowałem znaleźć odpowiedź na to pytanie, ale ostatecznie napisałem własną funkcję, która wyodrębnia wartości z formularza.
nie jest idealny, ale 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 parametrów (klucz -> wartość). dane wejściowe to element formularza (element DOM)
Nie obsługuje pól, które umożliwiają wielokrotny wybór.
new Array()
do inicjalizacji słownika. Ale z drugiej strony, kod wygląda o wiele czyściej niż niektóre bzdury, które napisałbym ostatnio!
Aktualizacja 2k20: użyj rozwiązania Josha z URLSearchParams.toString () .
Stara odpowiedź:
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('&');
W przypadku przeglądarek, które nie obsługują składni funkcji strzałek, która wymaga ES5, zmień .map...
wiersz na
.map(function(k) {return esc(k) + '=' + esc(params[k]);})
Jeśli używasz jQuery, możesz 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);
$.param($('#myform').serializeArray())
.
$('#myform').serialize()
jQuery !== JavaScript
jQuery.param()
tutaj github.com/jquery/jquery/blob/master/src/serialize.js :)
someStr=value1&someObj[a]=5&someObj[b]=6&someArr[]=1&someArr[]=2
Interfejs API URLSearchParams jest dostępny we wszystkich nowoczesnych przeglądarkach. Na przykład:
const params = new URLSearchParams({
var1: "value",
var2: "value2",
arr: "foo",
});
console.log(params.toString());
//Prints "var1=value&var2=value2&arr=foo"
params.append(key, value)
później dodać nowe parametry wyszukiwania w bardziej skomplikowanych scenariuszach.
x=null&y=undefined
const url = new URL("https://stackoverflow.com")
), możesz ustawić jego ciągi zapytań url.search = new URLSearchParams({foo: "bar"})
luburl.searchParams.append("foo", "bar")
To nie jest bezpośrednią odpowiedzią na twoje pytanie, ale oto ogólna funkcja, która utworzy adres URL zawierający parametry ciągu zapytania. Parametry (nazwy i wartości) są chronione za pomocą znaków zmiany znaczenia w celu umieszczenia ich w adresie 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
new Array
czas inicjować, kiedy faktycznie używasz jej jako obiektu? o, O
Wykorzystanie Object.entries()
, które zwraca tablicę [key, value]
par obiektów. Na przykład, {a: 1, b: 2}
ponieważ powróci[['a', 1], ['b', 2]]
. Nie jest obsługiwany (i nie będzie) tylko przez IE.
const buildURLQuery = obj =>
Object.entries(obj)
.map(pair => pair.map(encodeURIComponent).join('='))
.join('&');
buildURLQuery({name: 'John', gender: 'male'});
"name=John&gender=male"
Nie, nie sądzę, że standardowy JavaScript ma to wbudowane, ale Prototype JS ma tę funkcję (z pewnością większość innych frameworków JS też ma, ale ich nie znam), nazywają to serializacją .
Mogę polecić Prototype JS, działa całkiem nieźle. Jedyną wadą, jaką naprawdę zauważyłem, jest rozmiar (kilkaset kb) i zasięg (dużo kodu dla AJAX, DOM, itp.). Tak więc, jeśli chcesz tylko serializatora formularzy, jest to przesada, a ściśle mówiąc, jeśli chcesz mieć tylko funkcjonalność Ajax (do której głównie służyłem), to przesada. O ile nie jesteś ostrożny, może się okazać, że robi to trochę za dużo „magii” (jak na przykład rozszerzanie każdego elementu dom, którego dotyka za pomocą funkcji Prototype JS tylko po to, by znaleźć elementy), spowalniając go w skrajnych przypadkach.
Querystring może pomóc.
Więc możesz
const querystring = require('querystring')
url += '?' + querystring.stringify(parameters)
Jeśli nie chcesz korzystać z biblioteki, powinno to obejmować większość / wszystkie te same typy 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('&');
}
W rzeczywistości nie potrzebujesz formularza, aby to zrobić z Prototype. Po prostu użyj funkcji Object.toQueryString :
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'
W dzisiejszych czasach możesz to zrobić z FormData
i URLSearchParams
bez potrzeby zapętlania wszystkiego.
const formData = new FormData(form);
const searchParams = new URLSearchParams(formData);
const queryString = searchParams.toString();
Starsze przeglądarki będą jednak potrzebowały wypełnienia.
Sam nie jestem do końca pewien, pamiętam, że widziałem, jak jQuery zrobił to w pewnym stopniu, ale w ogóle nie obsługuje rekordów hierarchicznych, nie mówiąc już w sposób przyjazny dla php.
Jedną rzeczą, którą wiem na pewno, jest to, że podczas budowania adresów URL i wklejania produktu do domeny nie używaj do tego zwykłego kleju, bo otworzysz się na poręczny program do łamania stron.
Na przykład, niektóre programy reklamowe wstawiają ciąg znaków wersji z tego, co uruchamia twój flash. To jest w porządku, gdy jego ogólny prosty ciąg adobes, ale jest to bardzo naiwne i wybucha w zawstydzającym bałaganie dla ludzi, którzy zainstalowali Gnash, ponieważ ciąg wersji gnash zawiera pełną licencję praw autorskich GPL, wraz z adresami URL i <a href>. Użycie tego w generatorze reklamodawców typu string-glue powoduje otwarcie strony i wyświetlenie niezrównoważonego kodu HTML w domenie.
Morał tej historii:
var foo = document.createElement("elementnamehere");
foo.attribute = allUserSpecifiedDataConsideredDangerousHere;
somenode.appendChild(foo);
Nie:
document.write("<elementnamehere attribute=\""
+ ilovebrokenwebsites
+ "\">"
+ stringdata
+ "</elementnamehere>");
Google musi nauczyć się tej sztuczki. Próbowałem zgłosić problem, wydaje się, że ich to nie obchodzi.
Jak mówi Stein, możesz skorzystać z prototypowej biblioteki javascript ze strony http://www.prototypejs.org . Dołącz JS i to jest bardzo proste, $('formName').serialize()
zwróci to, co chcesz!
Dla tych z nas, którzy wolą jQuery, powinniście użyć wtyczki formularza: http://plugins.jquery.com/project/form , która zawiera metodę formSerialize.
Może być trochę zbędny, ale najczystszy sposób, jaki znalazłem, oparty na niektórych odpowiedziach tutaj:
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,
})
Te odpowiedzi są bardzo pomocne, ale chcę dodać kolejną odpowiedź, która może pomóc w utworzeniu pełnego adresu URL. To może pomóc concat podstawy url
, path
, hash
i parameters
.
var url = buildUrl('http://mywebsite.com', {
path: 'about',
hash: 'contact',
queryParams: {
'var1': 'value',
'var2': 'value2',
'arr[]' : 'foo'
}
});
console.log(url);
Możesz pobrać przez npm https://www.npmjs.com/package/build-url
Próbny:
;(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);
Wiem, że to bardzo późna odpowiedź, ale działa bardzo dobrze ...
var obj = {
a:"a",
b:"b"
}
Object.entries(obj).map(([key, val])=>`${key}=${val}`).join("&");
uwaga: obiekt.entries zwróci pary klucz, wartość
wyjście z powyższej linii będzie a = a & b = b
Mam nadzieję, że to komuś pomoże.
Miłego kodowania ...
Prawdopodobnie jest już za późno, aby odpowiedzieć na Twoje pytanie.
Miałem to samo pytanie i nie lubiłem nadal dołączać ciągów znaków, aby utworzyć adres URL. Więc zacząłem używać $ .param jak techhouse wyjaśnione.
Znalazłem również bibliotekę URI.js, która łatwo tworzy dla Ciebie adresy URL. Istnieje kilka przykładów, które pomogą Ci: URI.js Dokumentacja .
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"]);`
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>