只是想知道Javascript中是否有内置的东西可以接受表单并返回查询参数,例如:“var1=value&var2=value2&arr[]=foo&arr[]=bar…”

我已经想了很多年了。


我自己也不完全确定,我记得jQuery在一定程度上做到了这一点,但它根本不能处理分层记录,更不用说以php友好的方式了。

有一件事我很确定,当构建url并将产品粘贴到dom中时,不要仅仅使用字符串胶水来做,否则您将打开自己的方便之门。

For instance, certain advertising software in-lines the version string from whatever runs your flash. This is fine when its adobes generic simple string, but however, that's very naive, and blows up in an embarrasing mess for people whom have installed Gnash, as gnash'es version string happens to contain a full blown GPL copyright licences, complete with URLs and <a href> tags. Using this in your string-glue advertiser generator, results in the page blowing open and having imbalanced HTML turning up in the dom.

这个故事的寓意是:

   var foo = document.createElement("elementnamehere"); 
   foo.attribute = allUserSpecifiedDataConsideredDangerousHere; 
   somenode.appendChild(foo); 

不是:

   document.write("<elementnamehere attribute=\"" 
        + ilovebrokenwebsites 
        + "\">" 
        + stringdata 
        + "</elementnamehere>");

谷歌需要学习这个技巧。我试图报告这个问题,但他们似乎并不在意。


不,我认为标准JavaScript没有内置这个功能,但Prototype JS有这个功能(当然大多数其他JS框架也有,但我不知道它们),他们称之为序列化。

I can reccomend Prototype JS, it works quite okay. The only drawback I've really noticed it it's size (a few hundred kb) and scope (lots of code for ajax, dom, etc.). Thus if you only want a form serializer it's overkill, and strictly speaking if you only want it's Ajax functionality (wich is mainly what I used it for) it's overkill. Unless you're careful you may find that it does a little too much "magic" (like extending every dom element it touches with Prototype JS functions just to find elements) making it slow on extreme cases.


正如Stein所说,您可以使用http://www.prototypejs.org中的原型javascript库。 包括JS,这很简单,$('formName').serialize()将返回你想要的!


如果您不想使用库,这应该涵盖大多数/所有相同的表单元素类型。

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('&');
}

对于那些喜欢jQuery的人来说,你可以使用表单插件:http://plugins.jquery.com/project/form,它包含一个formSerialize方法。


你实际上不需要一个表单来做这个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'

这并没有直接回答您的问题,但这里有一个通用函数,它将创建一个包含查询字符串参数的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

如果你正在使用jQuery,你可能想要查看jQuery.param() http://api.jquery.com/jQuery.param/

例子:

var params = {
    parameter1: 'value1',
    parameter2: 'value2',
    parameter3: 'value3' 
};
var query = $.param(params);
console.log(query);

这将打印出:

parameter1=value1&parameter2=value2&parameter3=value3

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"

现在回答你的问题可能太迟了。 我有同样的问题,我不喜欢不断追加字符串创建URL。所以,我开始使用$。Param techhouse解释道。 我还找到了一个URI.js库,可以轻松地为您创建url。这里有几个例子可以帮助你: 这是其中之一:

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"]);`

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]);})

Querystring可以提供帮助。

所以,你可以

const querystring = require('querystring')

url += '?' + querystring.stringify(parameters)

URLSearchParams API在所有现代浏览器中都可用。例如:

const params = new URLSearchParams({ var1:“价值”, var2:“value2”, 加勒比海盗:“foo”, }); console.log (params.toString ()); / /打印“var1 = value&var2 = value2&arr = foo”


ES2017 (ES8)

利用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"

现在你可以用FormData和URLSearchParams做到这一点,而不需要循环任何东西。

const formData = new FormData(form);
const searchParams = new URLSearchParams(formData);
const queryString = searchParams.toString();

不过,旧的浏览器将需要一个填充。


这些答案是非常有用的,但我想添加另一个答案,这可能会帮助你建立完整的URL。 这可以帮助你连接基本url,路径,哈希和参数。

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 参数 = { 宽度:1680, 高度: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>


我知道这个回答有点晚了,但效果很好……

var obj = {
a:"a",
b:"b"
}

Object.entries(obj).map(([key, val])=>`${key}=${val}`).join("&");

注意:对象。条目将返回键、值对

上面一行的输出将是a=a&b=b

希望它能帮助到一些人。

快乐的编码…


可能有点多余,但我找到的最干净的方法是建立在这里的一些答案上:

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对象并将值附加到seachParameters

let stringUrl = "http://www.google.com/search";
let url = new URL(stringUrl);
let params = url.searchParams;
params.append("q", "This is seach query");

console.log(url.toString());

输出将是

http://www.google.com/search?q=This+is+seach+query

UrlSearchParams API是一个很好的建议,但我不敢相信没有人提到非常有用的.get和.set方法。它们可以用于操作查询字符串,不仅非常容易使用,还可以解决您可能遇到的许多问题。例如,在我的例子中,我想构建一个没有重复键的查询字符串。.set为您解决了这个问题。引用MDN文档:

URLSearchParams.set () 将与给定搜索参数关联的值设置为给定值。如果有多个值,则删除其他值。

示例(来自MDN):

let url = new URL('https://example.com?foo=1&bar=2');
let params = new URLSearchParams(url.search);

// Add a third parameter
params.set('baz', 3);

params.toString(); // "foo=1&bar=2&baz=3"

另一种更短的语法:

let url = new URL('https://example.com?foo=1&bar=2');

// Add a third parameter
url.searchParams.set('baz', 3);

url.searchParams.toString(); // "foo=1&bar=2&baz=3"