Просто интересно, есть ли что-нибудь встроенное в Javascript, которое может принимать форму и возвращать параметры запроса, например: "var1 = value & var2 = value2 & arr [] = foo & arr [] = bar..."
Я задавался вопросом об этом годами.
Просто интересно, есть ли что-нибудь встроенное в Javascript, которое может принимать форму и возвращать параметры запроса, например: "var1 = value & var2 = value2 & arr [] = foo & arr [] = bar..."
Я задавался вопросом об этом годами.
Я пытался найти ответ на этот вопрос некоторое время назад, но в итоге я написал свою собственную функцию, которая извлекает значения из формы.
это не идеально, но оно соответствует моим потребностям.
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 возвращает отображение (ключ → значение) параметров. вход является элементом формы (элемент DOM)
Он не обрабатывает поля, допускающие множественный выбор.
Без 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('&');
Для браузеров, которые не поддерживают синтаксис функции стрелки, для которой требуется ES5, измените строку .map...
на
.map(function(k) {return esc(k) + '=' + esc(params[k]);})
Если вы используете jQuery, вы можете проверить jQuery.param()
http://api.jquery.com/jQuery.param/
Пример:
var params = {
parameter1: 'value1',
parameter2: 'value2',
parameter3: 'value3'
};
var query = $.param(params);
document.write(query);
Это не дает прямого ответа на ваш вопрос, но вот общая функция, которая создаст URL-адрес, содержащий параметры строки запроса. Параметры (имена и значения) безопасно экранированы для включения в 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
Теперь для этого есть API, в частности API URLSearchParams. Для приведенного примера:
const params = new URLSearchParams();
const formvals = {
var1: "value",
var2: "value2",
arr: "foo",
};
for (const [key, val] of Object.entries(formvals)) {
params.append(key, val);
}
console.log(params.toString());
// var1=value&var2=value2&arr=foo
Примечание. В настоящее время он довольно совместим с Chrome и Firefox, но будьте осторожны, если вам нужно работать с браузерами Microsoft и Apple, поскольку совместимость является частичной.
С помощью jQuery вы можете сделать это с помощью $.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"
Использование Object.entries()
, который возвращает массив пар объект [key, value]
. Например, для {a: 1, b: 2}
будет возвращено [['a', 1], ['b', 2]]
. Это не поддерживается (и не будет) только IE.
const buildURLQuery = obj =>
Object.entries(obj)
.map(pair => pair.map(encodeURIComponent).join('='))
.join('&');
buildURLQuery({name: 'John', gender: 'male'});
"name=John&gender=male"
Нет, я не думаю, что стандартный JavaScript имеет встроенный, но у Prototype JS есть эта функция (конечно, большинство других JS-фреймворков тоже, но я их не знаю), они называют это serialize.
Я могу рекомендовать Prototype JS, он работает вполне нормально. Единственный недостаток, который я действительно заметил, это размер (несколько сотен килобайт) и объем (много кода для ajax, dom и т.д.). Таким образом, если вы хотите только сериализатор формы, он переборщит, и, строго говоря, если вы только хотите его функциональность Ajax (в основном это то, что я использовал), это излишне. Если вы не будете осторожны, вы обнаружите, что он делает слишком много "волшебства" (например, расширение каждого элемента dom затрагивает функции Prototype JS только для поиска элементов), что замедляет работу в экстремальных случаях.
Строка запроса может помочь.
Так что вы можете
const querystring = require('querystring')
url += '?' + querystring.stringify(parameters)
Если вы не хотите использовать библиотеку, это должно охватывать большинство/всех одинаковых типов элементов формы.
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('&');
}
Вам действительно не нужна форма для этого с Prototype. Просто используйте Функция 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'
Я не совсем уверен в себе, я напоминаю, что JQuery сделал это до некоторой степени, но он не обрабатывает иерархические записи вообще, не говоря уже о дружественном php.
Одна вещь, которую я знаю наверняка, заключается в том, чтобы создавать URL-адреса и вставлять продукт в дом, не просто использовать строковый клей, чтобы сделать это, либо вы откроете себя для удобного разрыва страницы.
Например, определенное рекламное ПО встраивает строку версии из того, что запускает вашу вспышку. Это прекрасно, когда его адомы генерируют простую строку, но, тем не менее, это очень наивно и взрывается в неудобной обстановке для людей, которые установили Gnash, поскольку строка версии gnash'es содержит полномасштабные лицензионные лицензии GPL, в комплекте с URL-адресами и < a href > теги. Используя это в генераторе-рекламодателе строкового клея, вы получите открытую страницу и неравномерную HTML-запись в dom.
Мораль истории:
var foo = document.createElement("elementnamehere");
foo.attribute = allUserSpecifiedDataConsideredDangerousHere;
somenode.appendChild(foo);
Не:
document.write("<elementnamehere attribute=\""
+ ilovebrokenwebsites
+ "\">"
+ stringdata
+ "</elementnamehere>");
Google должен изучить этот трюк. Я попытался сообщить о проблеме, они, похоже, не заботятся.
Как говорит Штайн, вы можете использовать прототип библиотеки javascript из http://www.prototypejs.org.
Включите JS, и это очень просто, $('formName').serialize()
вернет то, что вы хотите!
Для тех из нас, кто предпочитает jQuery, вы должны использовать плагин формы: http://plugins.jquery.com/project/form, который содержит метод formSerialize.
Вы можете сделать это в настоящее время с FormData
и URLSearchParams
без необходимости зацикливаться на чем-либо.
const formData = new FormData(form);
const searchParams = new URLSearchParams(formData);
const queryString = searchParams.toString();
Тем не менее, в старых браузерах потребуется полифилл.
Эти ответы очень полезны, но я хочу добавить еще один ответ, который может помочь вам создать полный URL. Это может помочь вам согласовать базовый url
, path
, hash
и parameters
.
var url = buildUrl('http://mywebsite.com', {
path: 'about',
hash: 'contact',
queryParams: {
'var1': 'value',
'var2': 'value2',
'arr[]' : 'foo'
}
});
console.log(url);
Вы можете скачать через npm https://www.npmjs.com/package/build-url
Демо-версия:
;(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);
Возможно, слишком поздно ответить на ваш вопрос.
У меня был тот же вопрос, и мне не нравилось добавлять строки добавления для создания URL-адреса. Итак, я начал использовать $.param как techhouse.
Я также нашел библиотеку URI.js, которая легко создает URL-адреса для вас. Есть несколько примеров, которые помогут вам: URI.js Документация.
Вот один из них:
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>