只是想知道Javascript是否内置了可以采用Form并返回查询参数的任何内容,例如: "var1=value&var2=value2&arr[]=foo&arr[]=bar..."
我多年来一直在想这个问题。
只是想知道Javascript是否内置了可以采用Form并返回查询参数的任何内容,例如: "var1=value&var2=value2&arr[]=foo&arr[]=bar..."
我多年来一直在想这个问题。
Answers:
一段时间之前,我试图寻找该问题的答案,但最终我写了我自己的函数,该函数从表单中提取值。
它不是完美的,但符合我的需求。
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更新:将Josh解决方案与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
URLSearchParams API在所有现代浏览器中均可用。例如:
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内置了该功能,但是Prototype JS具有该功能(当然大多数其他JS框架也具有此功能,但我不知道它们),他们称其为序列化。
我可以推荐Prototype JS,它还可以。我真正注意到的唯一缺点是它的大小(几百kb)和范围(很多有关ajax,dom等的代码)。因此,如果您只想要表单序列化程序,那就太过分了;严格来说,如果只想要Ajax功能(主要是我用过的功能),那就太过分了。除非您非常小心,否则您可能会发现它确实有点“神奇”(就像扩展它与Prototype JS函数所接触的每个dom元素只是为了查找元素一样),在极端情况下会变慢。
请求参数可以提供帮助。
这样你就可以
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'
我并不完全确定自己,我回想起jQuery在一定程度上做到了,但是它根本无法处理层次记录,更不用说以php友好的方式了。
我确实知道的一件事是,在构建URL并将产品粘贴到dom中时,不要仅仅使用string-glue来做到这一点,否则您将对一个方便的分页器敞开心opening。
例如,某些广告软件会从运行Flash的任何内容中内嵌版本字符串。当它禁止通用的简单字符串时,这很好,但是,这太幼稚了,对于安装了Gnash的人来说,它很混乱,因为gnash的版本字符串恰好包含完整的GPL版权许可,并带有URL和<a href>标签。在您的字符串胶水广告生成器中使用此功能,会导致页面打开并在dom中出现不平衡的HTML。
这个故事的主旨:
var foo = document.createElement("elementnamehere");
foo.attribute = allUserSpecifiedDataConsideredDangerousHere;
somenode.appendChild(foo);
不:
document.write("<elementnamehere attribute=\""
+ ilovebrokenwebsites
+ "\">"
+ stringdata
+ "</elementnamehere>");
Google需要学习这个技巧。我试图报告问题,他们似乎不在乎。
正如Stein所说,您可以使用http://www.prototypejs.org中的原型javascript库。包括JS,然后它非常简单,$('formName').serialize()
将返回您想要的!
可能有点多余,但我发现的最干净的方法是基于此处的一些答案:
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);
回答您的问题可能为时已晚。
我有同样的问题,我不想继续添加字符串以创建URL。因此,我开始使用$ .param,如技术专家所述。
我还找到了一个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"]);`