Цікаво, чи є у 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
час, коли ви насправді використовуєте її як об’єкт? o, O
Використання 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 є вбудований, але прототип JS має таку функцію (напевно, більшість інших фреймворків JS теж є, але я їх не знаю), вони називають це серіалізацією .
Я можу рекомендувати прототип JS, він працює цілком нормально. Єдиний недолік, який я дійсно помітив, це його розмір (кілька сотень кбіт) та масштабність (багато коду для ajax, dom тощо). Таким чином, якщо ви хочете лише серіалізатор форми, це надмірність, а якщо ви хочете, що це лише функціональність Ajax (для чого я в основному це використовував), це буде надмірне вбивство. Якщо ви не обережні, ви можете виявити, що це робить занадто багато "магії" (наприклад, розширення кожного елемента dom, який він торкається за допомогою прототипу 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('&');
}
Насправді вам не потрібна форма для цього з прототипом. Просто використовуйте функцію 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-адреси та вставляти виріб у дому, не використовуйте для цього лише рядок-клей, інакше ви відкриєте себе зручним вимикачем сторінок.
Наприклад, певне рекламне програмне забезпечення вбудовує рядок версії з будь-якого запуску флеш-версії. Це добре, коли його обоє простий рядок, але це дуже наївно, і це збентежило людей, які встановили Gnash, оскільки рядок версії gnash'es має містити повноцінні ліцензії на авторські права 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>