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

我已经想了很多年了。


当前回答

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"

其他回答

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"

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

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

不,我认为标准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()将返回你想要的!

我自己也不完全确定,我记得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>");

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