【问题标题】:How to send an ajax request on form submit without affecting the actual form如何在表单提交时发送ajax请求而不影响实际表单
【发布时间】:2020-11-08 09:52:21
【问题描述】:

我想创建一个注册表单来验证您的输入,然后向 PHP 页面发送 AJAX 请求以检查您的用户名是否已被使用。之后它将提交实际的表单(位置在一个动作属性中)。

function validate() {
  if (fullname.length < 90) { /*this is validating the form*/
    var username_input = document.forms["myform"]["username"].value;
    if (window.XMLHttpRequest) {
      var usernamecheck = new XMLHttpRequest();
    } else if (window.ActiveXObject) {
      var usernamecheck = new ActiveXObject("Microsoft.XMLHTTP");
    }
    usernamecheck.open("POST", "reciever.php", true);
    usernamecheck.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    usernamecheck.send("user=" + username_input); /*sending username to check if it exists*/
    usernamecheck.onreadystatechange = function() {
      if (usernamecheck.readyState == 4 && this.status == 200) {
        if (usernamecheck.responseText == "user") {
          alert('username has already been used');
          return false;
        }
      }
    };

    var contactcheck = new XMLHttpRequest(); /*second request*/
    contactcheck.open("POST", "reciever.php", true);
    contactcheck.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    contactcheck.send("contact=" + contactw);
    contactcheck.onreadystatechange = function() {
      if (contactcheck.readyState == 4 && this.status == 200) {
        if (contactcheck.responseText == "contact") {
          alert('email has already been used');
          return false;
        }
      }
    };
  }
  /*reference 1 (see below)*/
}

我的问题是表单在 AJAX 运行之前就提交了,如果我在脚本显示“引用 1”的地方添加 return false;,AJAX 就会运行,但表单没有提交。

【问题讨论】:

  • 能否添加监听提交事件的部分并调用validate 函数。这需要在IE9及以下的旧机器上运行吗?

标签: javascript ajax ajaxform


【解决方案1】:

您的问题与此类似:

check if username exists in real-time through AJAX in php with mysql

引用帖子:

“像这样使用 jQuery 在 javascript 中发送您的数据:”

$.post( "check.php", { user: $("#username").val() }, function (data){
  if(data=='1'){
   //do 1
  }
  elseif(data=='0'){
    //do 0
  }
});

在你的 check.php 中获取这样的用户名

//some basic validation
if(!isset($_POST['user'] || empty($_POST['user']))
{

       echo '0'; exit();
    }

$username = trim($_POST['user']); 

“为了让它正常工作,你 check.php 必须返回 1 或 0,不要在此处或任何地方回显 mysql 错误。如果发生任何错误,只需回显 0。”

【讨论】:

    【解决方案2】:

    如果您的函数用作事件处理程序,例如addEventListener('submit', validate)onsubmit="validate()",那么您应该检查Event 对象发送与提交事件并防止表单的默认提交行为。

    您可以使用event.preventDefault() 方法来做到这一点,就像它所说的那样,它可以防止表单的默认行为,即提交。

    但是您的return false 语句不起作用的原因是XMLHttpRequest.send() 的异步性质。这意味着该函数不会等待 return 语句,因为它位于稍后调用的函数内部。他的行为的原因是让其他代码在您等待服务器响应时运行,而不是在请求完成之前等待代码。

    您还可以在一个请求中向服务器发送多个值,而不是执行两个单独的请求。应尽可能优化 AJAX 请求,因为它们(可能)对客户端和服务器都造成负担。

    请参阅下面的 sn-ps,了解如何完成上述所有操作。

    function validate(event) {
      if (fullname.length >= 90) {
        return; // Stop function if condition is not met.
      }
      event.preventDefault(); // Prevent form from submitting.
      var form = event.target; // The target is the form that is submitting.
      var userName = form.elements['username'].value;
      var email = form.elements['email'].value; // I assume this was missing.
      var request;
      if (window.XMLHttpRequest) {
        request = new XMLHttpRequest();
      } else if (window.ActiveXObject) {
        request = new ActiveXObject("Microsoft.XMLHTTP");
      }
      request.open("POST", "reciever.php", true);
      request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
      request.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
          var response = this.responseText;
          if (response === "user") {
            alert('Username has already been used');
          } else if (response === "email") {
            alert('Email has already been used');
          }
        }
      };
      request.send('user=' + userName + '&email=' + email); // Send both user name and email values.
    }
    

    您似乎使用了像ActiveXObject 这样的遗留代码,当前浏览器不再使用它。如果您真的需要它用于较旧的浏览器,那么您很好。如果您喜欢更现代的方法并且不需要支持旧浏览器,请查看下面的示例。它(几乎)做同样的事情,但语法不同。

    const alerts = {
      'user': 'Username has already been used',
      'email': 'Email has already been used'
    };
    
    async function validate(event) {
      if (fullname.length >= 90) return; 
      event.preventDefault();
      const formData = new FormData(event.target);
      try {
        const response = await fetch('reciever.php', {
          method: 'POST',
          body: formData
        }
        if (!response.ok) {
          throw new Error(`
            Check has failed. - 
            ${response.status}: 
            ${response.statusText}`
          );
        }
        const text = await response.text();
        if (text in alerts) alert(alerts[text]);
      } catch (error) {
        console.error(error);
      }
    }
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-02-26
      • 1970-01-01
      • 2021-10-12
      • 1970-01-01
      • 2015-10-10
      • 1970-01-01
      • 2013-10-23
      • 1970-01-01
      相关资源
      最近更新 更多