Просто интересно, есть ли что-нибудь встроенное в 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)
Он не обрабатывает поля, которые допускают множественный выбор.
new Array()
для инициализации словаря. Но опять же, код выглядит намного чище, чем та чушь, которую я бы написал в эти дни!
Обновление 2k20: используйте решение Джоша с URLSearchParams.toString () .
Старый ответ:
Без 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);
$.param($('#myform').serializeArray())
.
$('#myform').serialize()
jQuery !== JavaScript
jQuery.param()
здесь github.com/jquery/jquery/blob/master/src/serialize.js :)
someStr=value1&someObj[a]=5&someObj[b]=6&someArr[]=1&someArr[]=2
API URLSearchParams доступен во всех современных браузерах. Например:
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)
позже для добавления новых параметров поиска в более сложных сценариях.
x=null&y=undefined
const url = new URL("https://stackoverflow.com")
), вы можете установить его строки запроса url.search = new URLSearchParams({foo: "bar"})
илиurl.searchParams.append("foo", "bar")
Это не дает прямого ответа на ваш вопрос, но вот общая функция, которая создаст 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
new Array
время, когда вы фактически используете ее как объект? о, о
Использование 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 тоже есть, но я их не знаю), они называют ее сериализацией. .
Я могу порекомендовать 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'
Вы можете сделать это в настоящее время с FormData
и URLSearchParams
без необходимости зацикливаться на чем-либо.
const formData = new FormData(form);
const searchParams = new URLSearchParams(formData);
const queryString = searchParams.toString();
Тем не менее, в старых браузерах потребуется полифилл.
Я не совсем уверен, я помню, что jQuery делал это до некоторой степени, но он вообще не обрабатывает иерархические записи, не говоря уже о php-дружественном способе.
Я точно знаю одну вещь: когда вы создаете URL-адреса и вставляете продукт в dom, не просто используйте для этого строковый клей, иначе вы откроете себя для удобного средства разбиения страниц.
Например, определенное рекламное программное обеспечение вставляет строку версии из того, что запускает вашу флеш-память. Это хорошо, когда он использует общую простую строку, но, тем не менее, это очень наивно и взрывается в смущающем беспорядке для людей, которые установили Gnash, поскольку строка версии gnash'а содержит полную лицензию на авторские права GPL с URL-адресами. и <a href> теги. Использование этого в генераторе рекламодателя со связыванием строк приводит к тому, что страница открывается, и в домене появляется неуравновешенный HTML.
Мораль этой истории:
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.
Может быть, немного излишним, но самый чистый способ, который я нашел, основывается на некоторых из ответов здесь:
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,
})
Эти ответы очень полезны, но я хочу добавить еще один ответ, который может помочь вам создать полный URL. Это может помочь вам CONCAT базы 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);
Я знаю, что это очень поздний ответ, но работает очень хорошо ...
var obj = {
a:"a",
b:"b"
}
Object.entries(obj).map(([key, val])=>`${key}=${val}`).join("&");
примечание: object.entries вернет ключ, пары значений
Выходная информация из вышеуказанной строки будет a = a & b = b
Надеюсь, это поможет кому-то.
Удачного кодирования ...
Возможно, уже слишком поздно, чтобы ответить на ваш вопрос.
У меня был тот же вопрос, и я не хотел добавлять строки для создания 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>