纯Javascript中的AJAX发布实现[重复]

Posted

技术标签:

【中文标题】纯Javascript中的AJAX发布实现[重复]【英文标题】:AJAX Post Implementation in Pure Javascript [duplicate] 【发布时间】:2015-08-05 12:28:25 【问题描述】:

在纯 javascript 中是否有任何 AJAX Post 实现(可能使用 xmlhttprequest)?

例如,如果我有这样的表格:

<form action="request.php" id="register_form">
  <input type="text" name="first_name" placeholder="First Name">
  <input type="text" name="last_name" placeholder="LastName">
  <input type="submit" value="submit_now">
</form>

这是我在 jQuery 中的 AJAX 实现

$('#register_form').submit(function(e) 

var postData = $(this).serializeArray();
var formURL = $(this).attr("action");

/* start ajax submission process */
$.ajax(
    url: formURL,
    type: "POST",
    data: postData,
    success: function(data, textStatus, jqXHR) 
        alert('Success!');
    ,
    error: function(jqXHR, textStatus, errorThrown) 
        alert('Error occurred!');
    

);

e.preventDefault(); //STOP default action

/* ends ajax submission process */

);

我可以不使用 jQuery 做同样的事情吗?如果可能,如何将上述 jQuery 代码实现为纯/纯 Javascript 代码?

【问题讨论】:

我这里有 3 个问题,由@DDeme 解决,即:1. 捕获事件,以及纯 JS 中的 e.preventDefault 替代方案,2. serializeArray();在纯 JS 中实现,以及 3. 获取 AJAX 查询/替代成功的状态:和错误:。我可以说它与您上面提到的不重复 【参考方案1】:

是的,当然这是可能的:)

<form action="request.php" id="register_form">
  <input class='formVal' type="text" name="first_name" placeholder="First Name">
  <input class='formVal' type="text" name="last_name" placeholder="LastName">
  <input type="submit" value="submit_now" onclick="myFunction(); return false;">
</form>

JS

function myFunction()

    var elements = document.getElementsByClassName("formVal");
    var formData = new FormData(); 
    for(var i=0; i<elements.length; i++)
    
        formData.append(elements[i].name, elements[i].value);
    
    var xmlHttp = new XMLHttpRequest();
        xmlHttp.onreadystatechange = function()
        
            if(xmlHttp.readyState == 4 && xmlHttp.status == 200)
            
                alert(xmlHttp.responseText);
            
        
        xmlHttp.open("post", "server.php"); 
        xmlHttp.send(formData); 

server.php

<?php
   $firstName = $_POST["first_name"];
   $lastName = $_POST["last_name"];
   echo $firstName." ".$lastName;
   //enter name and lastname into your form and onclick they will be alerted 
?>

解释: 函数通过类名获取表单元素并将它们存储在数组中。然后我们创建 FormData 对象并循环遍历每个元素的元素数组,并将它们的名称和值附加到 FormData 对象。 之后,我们创建 XMLHttpRequest() 对象来监控请求期间的状态和状态变化,并使用 post 方法将数据发送到 server.php 当它结束并且readystate等于4并且status等于200时,我们警告来自server.php的响应,我们保存在XMLHttpRequest对象的responseText属性中。

【讨论】:

您好,请问如何知道表单是否提交成功? @FarizLuqman 我刚刚发现了一些错误并修复了它,再次复制/粘贴我的答案并检查:) 这段代码就像魔法一样工作! +1并被接受为答案!你解决了我的 3 个问题,使用 onclick="myFunction(); return false;" 捕获事件,替代序列化数据,并获取 ajax 查询的状态。谢谢我的朋友! @FarizLuqman 谢谢他,总是很乐意分享我的知识:) 如果你使用 Laravel 和 CSRF 保护然后添加 到您的表单。它对我有用,谢谢。【参考方案2】:

当然,您可以使用Ajax only Reqwest lib。

类似:

reqwest(
    url: 'path/to/json'
  , type: 'json'
  , method: 'post'
  , error: function (err)  
  , success: function (resp) 
      qwery('#content').html(resp.content)
    
)

根据他们的自述文件,您可以使用:

$(form).serialize()

【讨论】:

来吧,你想完成所有工作吗?? 你好@Jonatas,为 Reqwest 库 +1!【参考方案3】:

是的。

正如你所说,它适用于XMLHttpRequest。

var http = new XMLHttpRequest();
var postData = serialize(arr);
var params = "postdata=" + postData;
http.open("POST", url, true);
http.send(params);

对于序列化函数是 JS 参见this page。

function serialize(mixed_value) 
  //  discuss at: http://phpjs.org/functions/serialize/
  // original by: Arpad Ray (mailto:arpad@php.net)
  // improved by: Dino
  // improved by: Le Torbi (http://www.letorbi.de/)
  // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net/)
  // bugfixed by: Andrej Pavlovic
  // bugfixed by: Garagoth
  // bugfixed by: Russell Walker (http://www.nbill.co.uk/)
  // bugfixed by: Jamie Beck (http://www.terabit.ca/)
  // bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net/)
  // bugfixed by: Ben (http://benblume.co.uk/)
  //    input by: DtTvB (http://dt.in.th/2008-09-16.string-length-in-bytes.html)
  //    input by: Martin (http://www.erlenwiese.de/)
  //        note: We feel the main purpose of this function should be to ease the transport of data between php & js
  //        note: Aiming for PHP-compatibility, we have to translate objects to arrays
  //   example 1: serialize(['Kevin', 'van', 'Zonneveld']);
  //   returns 1: 'a:3:i:0;s:5:"Kevin";i:1;s:3:"van";i:2;s:9:"Zonneveld";'
  //   example 2: serialize(firstName: 'Kevin', midName: 'van', surName: 'Zonneveld');
  //   returns 2: 'a:3:s:9:"firstName";s:5:"Kevin";s:7:"midName";s:3:"van";s:7:"surName";s:9:"Zonneveld";'

  var val, key, okey,
    ktype = '',
    vals = '',
    count = 0,
    _utf8Size = function (str) 
      var size = 0,
        i = 0,
        l = str.length,
        code = '';
      for (i = 0; i < l; i++) 
        code = str.charCodeAt(i);
        if (code < 0x0080) 
          size += 1;
         else if (code < 0x0800) 
          size += 2;
         else 
          size += 3;
        
      
      return size;
    ,
  _getType = function (inp) 
    var match, key, cons, types, type = typeof inp;

    if (type === 'object' && !inp) 
      return 'null';
    

    if (type === 'object') 
      if (!inp.constructor) 
        return 'object';
      
      cons = inp.constructor.toString();
      match = cons.match(/(\w+)\(/);
      if (match) 
        cons = match[1].toLowerCase();
      
      types = ['boolean', 'number', 'string', 'array'];
      for (key in types) 
        if (cons == types[key]) 
          type = types[key];
          break;
        
      
    
    return type;
  ,
  type = _getType(mixed_value);

  switch (type) 
  case 'function':
    val = '';
    break;
  case 'boolean':
    val = 'b:' + (mixed_value ? '1' : '0');
    break;
  case 'number':
    val = (Math.round(mixed_value) == mixed_value ? 'i' : 'd') + ':' + mixed_value;
    break;
  case 'string':
    val = 's:' + _utf8Size(mixed_value) + ':"' + mixed_value + '"';
    break;
  case 'array':
  case 'object':
    val = 'a';
    /*
        if (type === 'object') 
          var objname = mixed_value.constructor.toString().match(/(\w+)\(\)/);
          if (objname == undefined) 
            return;
          
          objname[1] = this.serialize(objname[1]);
          val = 'O' + objname[1].substring(1, objname[1].length - 1);
        
        */

    for (key in mixed_value) 
      if (mixed_value.hasOwnProperty(key)) 
        ktype = _getType(mixed_value[key]);
        if (ktype === 'function') 
          continue;
        

        okey = (key.match(/^[0-9]+$/) ? parseInt(key, 10) : key);
        vals += this.serialize(okey) + this.serialize(mixed_value[key]);
        count++;
      
    
    val += ':' + count + ':' + vals + '';
    break;
  case 'undefined':
    // Fall-through
  default:
    // if the JS object has a property which contains a null value, the string cannot be unserialized by PHP
    val = 'N';
    break;
  
  if (type !== 'object' && type !== 'array') 
    val += ';';
  
  return val;

【讨论】:

是的,但是如何将上面的 jQuery 代码实现到 XMLHttpRequest 尤其是序列化部分?这部分给了我相当长的时间在谷歌中用纯 JS 实现。以及如何获得成功/错误部分?谢谢! 答案应该包含实际的解决方案,而不仅仅是一个链接。 +1 用于纯 JS 中的序列化实现。我很抱歉 -1 我不知道是谁干的以及为什么这样做 我想是你面前的评论员。 @Musa:很高兴您知道缺少哪些并且不提供这些知识...

以上是关于纯Javascript中的AJAX发布实现[重复]的主要内容,如果未能解决你的问题,请参考以下文章

用纯 JavaScript 解析 JSON [重复]

使用纯 Javascript 通过 AJAX 发送 WordPress 对象

6.Ajax技术

纯 JavaScript 的 AJAX 请求出现“ActionController::InvalidCrossOriginRequest”错误

AJAX中的dataType

Javascript:等到ajax请求完成关闭页面[重复]