You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

同时通过HTML表单与AJAX发送两个POST请求的跨浏览器问题

问题描述

我尝试向不同站点发送两个POST请求:一个通过表单action属性发送,另一个在onsubmit事件中使用AJAX(XMLHttpRequest)发送。代码在Chrome浏览器中可正常运行(先发送AJAX POST请求,再发送表单POST请求),但在Firefox中仅能发送表单action的POST请求,AJAX请求无法触发。

表单POST代码

<form name="form_log" method="POST" action="Site1.php" onsubmit="return validate(this);">
    <input type="text" name="username">
    <input type="password" name="password">
    <input type="submit" name="Submit" value="Enter">
</form>

AJAX POST代码

function validate(){
    if(document.form_log.username.value == ""){
        alert('User name is empty');
        return false;
    }

    if(document.form_log.password.value == ""){
        alert('Password is empty');
        return false;
    }
    else{
        var user=document.getElementsByName('username')[0].value;
        var pass=document.getElementsByName('password')[0].value;
        var parameters=`username=${user}&password=${pass}&Submit=Enter`;
        var url = "http://Site2.php";
        var xhttp = new XMLHttpRequest();
        xhttp.open('POST',url,true);

        xhttp.setRequestHeader('Content-type','application/x-www-form-urlencoded');

        xhttp.onreadystatechange = ()=>{
            if(xhttp.DONE && xhttp.status == 200){
                console.log("SENT!");
            }
        }
        xhttp.send(parameters);
    }   
}
问题原因与解决办法

这是因为你使用了异步AJAX请求(xhttp.open的第三个参数为true),Firefox在表单触发页面跳转前,会直接终止当前页面的进程,导致未完成的异步AJAX请求被取消;而Chrome有特殊机制允许异步请求在页面卸载前完成。

解决方法1:改用同步AJAX请求

将xhttp.open('POST',url,true)改为xhttp.open('POST',url,false),让AJAX请求完成后再执行表单提交。但此方法会阻塞页面,影响用户体验,且现代浏览器对主线程同步请求有一定限制。

修改后的关键代码片段:

xhttp.open('POST',url,false); // 第三个参数改为false,启用同步请求

解决方法2:先阻止表单默认提交,AJAX完成后手动提交表单

这种方式更友好,不会阻塞页面:

  1. 让validate函数默认返回false,阻止表单自动提交;
  2. 在AJAX的onreadystatechange回调中,请求完成后手动调用表单的submit()方法。

修改后的完整代码:

function validate(){
    if(document.form_log.username.value == ""){
        alert('User name is empty');
        return false;
    }

    if(document.form_log.password.value == ""){
        alert('Password is empty');
        return false;
    }
    
    var user=document.getElementsByName('username')[0].value;
    var pass=document.getElementsByName('password')[0].value;
    // 用URLSearchParams处理参数,避免编码问题
    var params = new URLSearchParams();
    params.append('username', user);
    params.append('password', pass);
    params.append('Submit', 'Enter');
    
    var url = "http://Site2.php";
    var xhttp = new XMLHttpRequest();
    xhttp.open('POST',url,true);

    xhttp.setRequestHeader('Content-type','application/x-www-form-urlencoded');

    xhttp.onreadystatechange = ()=>{
        if(xhttp.DONE){
            console.log("AJAX请求完成");
            // 手动提交表单
            document.form_log.submit();
        }
    }
    xhttp.send(params);
    
    // 阻止表单默认提交行为
    return false;
}

额外注意事项

  • 如果Site2.php与当前页面不同域,需确保目标服务器配置了CORS(跨域资源共享),否则AJAX请求会被浏览器拦截;
  • 避免直接用模板字符串拼接参数,容易出现编码错误,推荐使用URLSearchParams处理参数。

内容的提问来源于stack exchange,提问作者OJR

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 04:46:46