【问题标题】:Javascript / AJAX - get parameter array from formJavascript / AJAX - 从表单获取参数数组
【发布时间】:2012-01-07 07:59:41
【问题描述】:

我有这个表单,它生成一个数组作为输出,我想通过 AJAX 将它发送到 PHP 页面。 表单是这样构建的:[使用更多条目]

 <input type="hidden" name="reisdata[Van]" value="'.$reisdata["Van"].'">
 <input type="hidden" name="reisdata[Naar]" value="'.$reisdata["Naar"].'">

并且php页面需要以数组的形式接收数据。

现在,有人向我展示了这段代码,通过 POST 在 AJAX 中传递一个数组,但我仍然不知道如何在 javascript 中读取该数组。

那么:我如何在 AJAX / Javascript 中从表单中读取数组? 我只是通过键入:document.formname.reisdata 来阅读它吗?

这是我的 AJAX 代码:

// Algemene functie om een xmlHttp object te maken. Via dit object kunnen we later Ajax calls plaatsen

function GetXmlHttpObjectReisData() {
    var xmlHttp;
    try { // Firefox, Opera 8.0+, Safari
        xmlHttp = new XMLHttpRequest();
    } 
    catch (e) { // Internet Explorer
        try { xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
        } 
        catch (e) {
            try { xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
            } 
            catch (e) {
                alert("Your browser does not support AJAX!");
                return false;
            }
        }
    }
    return xmlHttp;
}
function CallAjaxReisDataFunction(serverScript,arguments)
{
    var xmlHttp = new GetXmlHttpObjectReisData(); // Functie welke wordt uitgevoerd als de call naar de server klaar is State 4)
    xmlHttp.onreadystatechange = function()
    {
        if (xmlHttp.readyState == 4) 
        {
            handleReisDataResult(xmlHttp.responseText);
        }
    }

    // Ajax call (Request naar de server met eventuele parameters (arguments))
    xmlHttp.open("POST", serverScript, true);
    xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    xmlHttp.setRequestHeader("Content-length", arguments.length);
    xmlHttp.setRequestHeader("Connection", "close");
    xmlHttp.send(arguments);
}

function callReisDataServer(serverScript,van,naar)
{
    CallAjaxReisDataFunction(serverScript,"?&reisdata=" + reisdata);
}

function handleReisDataResult(responseText)
{
    document.getElementById('reis').innerHTML = responseText;
}

这是某人 (@mephisto123) 之前给我的代码,但这适用于预定义的 javascript 数组:

var postdata = {"provincie":"123","reisdata":{"Overstap":"234","Van":"345"}};
var post = "";
var url = "data-reis-refresh.php";
var key, subkey;
for (key in postdata) {
    if (typeof(postdata[key]) == object) {
        foreach (subkey in postdata[key]) {
            if (post != "") post += "&";
            post += key + "%5B" + subkey + "%5D=" + postdata[key][subkey];
        }
    }
    else post += key + "=" + postdata[key];
}
req.open("POST", url, true);
req.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT");
req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
req.setRequestHeader("Content-length", post.length);
req.setRequestHeader("Connection", "close");
req.send(post);

【问题讨论】:

  • 当您说要从 JavaScript 中的 submitted 表单中读取数组时,不清楚您的意思。表单已提交到您的服务器,不是吗?而且你说服务器代码是PHP。
  • 对不起,这确实有点奇怪。我应该把提交的部分排除在外。应该是:表单提交时从表单中读取数组(当我使用:document.forms[formname].submit();)
  • 那么,为什么在提交时需要“读取数组”?您需要做的就是为 AJAX 请求构建参数,并且表单字段名称显然已经是服务器期望的格式。 (如果不是,那为什么用这样的字段名创建表单?)
  • 另外,我一般不喜欢推荐 JavaScript 框架,但这种特殊情况是考虑 Prototype、jQuery 或任何支持 AJAX 的简单框架的一个很好的理由。此类库会为您处理一些浏览器怪癖,它确实大大简化了该过程。但是,如果您愿意,您当然可以自己完成所有操作。
  • 如果在使用 JQuery 时这很容易,我完全赞成。但是,你能告诉我怎么做吗?

标签: javascript ajax arrays forms


【解决方案1】:

致所有读者: 最后,我最终使用了 jQuery .post() 和 .get()。 它们非常易于使用,而且速度更快、更灵活。

【讨论】:

    【解决方案2】:

    如果字段名称是用这样的名称生成的,那么就没有什么特别的事情要做了。只需收集表单参数,对名称和值进行 URL 编码,然后 POST 到服务器。 (这个过程并不简单,因为您需要对不同类型的表单元素及其值的确定方式保持敏感,但复杂性与字段名称的外观无关。)

    作为术语说明,在 JavaScript 中,Array 实例是按数字索引的。一般来说,使用字符串属性名称是 JavaScript 对象的一种能力,如果您不想让 JavaScript 程序员感到困惑,或者给您这样的迂腐指令,则不要指代“数组”之类的东西 :-)

    同样,在这种情况下,您只是获得了具有“有趣”名称的表单字段,而 JavaScript 并不特别关心这一点。

    edit — 下面是一个快速尝试序列化表单中所有元素的函数:

    function serialize( form ) {
      var rv = [], el = null, opt = null;
      form = form || document.forms[0];
    
      function ffv( name, value ) {
        return encodeURIComponent(name) + '=' + encodeURIComponent(value);
      }
    
      for (var i = 0; i < form.elements.length; ++i) {
        var el = form.elements[i];
        switch (el.tagName) {
          case 'INPUT': {
            switch (el.type.toLowerCase()) {
              case 'checkbox':
              case 'radio':
                if (el.checked)
                  rv.push( ffv(el.name, el.value) );
                break;
              case 'text':
              case 'password':
              case 'hidden':
                rv.push( ffv(el.name, el.value) );
                break;
            }
            break;
          }
          case 'SELECT': {
            opt = el.options[el.selectedIndex];
            rv.push( ffv(el.name, opt.value || opt.innerText) );
            break;
          }
          case 'TEXTAREA': {
            rv.push( ffv(el.name, el.value) );
            break;
          }
        }
      }
      return rv.join('&');
    }
    

    然后,当您在 XHR 对象上调用“.send()”时,您将调用该函数:

    req.send( serialize() );
    

    默认情况下,编写的函数将序列化页面上的第一个表单。如有必要,您可以显式地传递一个表单。我猜旧版本的 IE 可能存在一些问题;特别是我不记得“innerText”是否总是适用于&lt;option&gt; 元素。

    该函数所做的是查看每个表单元素,确定其值(以及是否应该将其包含在提交中),然后创建表单的名称/值对

    名称=值

    名称和值都首先在内部“ffv()”函数中编码,因此您的字段最终看起来像

    reisdata%5BNaar%5D=某事

    然后将整个输入列表与“&”连接在一起,以创建要传递给 PHP(或任何其他服务器端语言)的整体参数集。

    如果您想尝试 jQuery,那么整个事情会变得非常容易。有一个丰富的 AJAX 操作 API,但在您的情况下,它可能很简单

    $.post( url, $('form').serialize(), function( result ) { ... } );
    

    【讨论】:

    • 那么,您是说 Javascript 不能处理关联数组,但它会正确处理我的关联数组吗?现在这对我来说似乎有点奇怪?另外,我可以在我的代码中使用它吗? var postdata document.formname.reisdata
    • JavaScript 对象可以具有以字符串命名的属性,但它们通常不称为“关联数组”(在 JavaScript 中)。真正的重点是,甚至不需要尝试创建一个反映服务器端关联数组结构的 JavaScript 对象,因为表单(根据您问题中的 HTML)已经具有反映这一点的字段名称。
    • 哦,好吧,这听起来很合理!那么使用代码var postdata document.formname.reisdata 会起作用吗? (其中 document.formname.reisdata 将是关联数组/javascript 对象,而不是手动输入的数组?)
    • 我不知道为什么它不会加载,但我只是更仔细地查看了代码,无论如何它都坏了:-)我会更新我的答案。
    • 好的,我会添加一个简短的描述。
    猜你喜欢
    • 2017-07-02
    • 2013-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多