没有jQuery的AJAX不会将POST数据发送到PHP文件


AJAX without jQuery is not sending POST data to PHP file

几天来我一直在尝试让 ajax 警报层使用 POST 方法,但我想不出它不起作用的原因。我使用相同的基本代码在其他管理页面上通过 ajax 和 POST 发送表单数据,没有遇到任何问题,但是当我尝试发送不是来自表单的数据时,没有任何内容以 $_POST 的价格进入服务器。

这是代码的流程...

我在这样的页面上使用变量:

$alertLayer = 1;
$autoCloseAlertLayer = 1;
$addAlertLayerCloseButton = 1;
$alertLayerMessage = $alertLayerMessage . '<h1>Test</h1><p>3rd test of the alert layer module.</p>';
$redirect = 0;
$redirectTo = 0;

我在页面底部包含一个调用函数的脚本,如下所示:

if ($alertLayer == true)
{   
    echo "<script type='text/javascript' id='alertLayerScript'>Lib.ajaxAlertFunction('/Modules/AlertLayer', $autoCloseAlertLayer, $addAlertLayerCloseButton, '$alertLayerMessage', $redirect, '$redirectTo');</script>";
}

下面是调用的脚本:

Lib.ajaxAlertFunction = function (senturl, autoClose, closeButton, message, redirect, redirectTo)
{   
var ajaxRequest;
try
{
    ajaxRequest = new XMLHttpRequest();
}
catch (e)
{
    try
    {
        ajaxRequest = new ActiveXObjext("Msxml2.XMLHTTP");
    }
    catch (e)
    {
        try
        {
            ajaxRequest = new ActiveXObjext("Microsoft.XMLHTTP");
        }
        catch (e)
        {
            alert ("Your browser can't handle the truth!");
            return false;
        }
    }
}
if (!senturl)
{
    return false;
}
else
{
    // var data = "autoClose=" + encodeURIComponent(autoClose) + "&closeButton=" + encodeURIComponent(closeButton) + "&message=" + encodeURIComponent(message) + "&redirect=" + encodeURIComponent(redirect) + "&redirectTo=" + encodeURIComponent(redirectTo);
    // var data = encodeURIComponent("autoClose=" + autoClose + "&closeButton=" + closeButton + "&message=" + message + "&redirect=" + redirect + "&redirectTo=" + redirectTo);
    var data = "autoClose=" + autoClose + "&closeButton=" + closeButton + "&message=" + message + "&redirect=" + redirect + "&redirectTo=" + redirectTo;
}
ajaxRequest.onreadystatechange = function()
{
    if (ajaxRequest.readyState == 4 && ajaxRequest.status == 200)
    {
        document.getElementById('outerFrame').innerHTML += ajaxRequest.responseText;
        newAlertLayer = document.getElementById('alertLayer');
        var arr = newAlertLayer.getElementsByTagName('script')
        for (var n = 0; n < arr.length; n++)
        {
            eval(arr[n].innerHTML)
        }
    }
}
ajaxRequest.open('POST', senturl, true);
ajaxRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
ajaxRequest.send(data);
}

注意:我使用"GET"方法发送此数据没有问题,但随后一条长消息被切断。我还尝试在过去 3 天内搜索的几种不同方法中设置"data"变量,但没有成功。

需要 $_POST 数据的代码如下所示:

<?php
$ROOT = $_SERVER['DOCUMENT_ROOT'];
?>
<div id="alertLayer">
<link rel="stylesheet" href="<?php $ROOT ?>/Modules/AlertLayer/alertLayer.css">
<script src="/Modules/AlertLayer/alertLayer.js"></script>
<div id="alertBlock">
<?php
foreach ($_POST as $key => $value)
{
    echo "<p>" . $key . " = " . $value . "</p>";
}
foreach ($_GET as $key => $value)
{
    echo "<p>" . $key . " = " . $value . "</p>";
}
?>
</div>
</div>

我错过了什么?与使用 POST 发送表单数据和以相同方式连接的发送变量有什么不同?同样,当我将数据添加到 url 字符串时,GET 正在工作,但还不够,POST = 在 ajaxRequest 的另一端根本没有收到任何数据,但请求的其余部分完全返回预期的内容。服务器请求中缺少的 $_POST 数据是目前我无法使用此代码解决的唯一问题。

看起来请求未正确发送,但我无法确定原因。以下是 chrome 中"网络"选项卡的屏幕截图:

问题是nginx发出的重定向(301(,原因是URL末尾缺少斜杠。这导致 POST 请求更改为 GET。

技术细节:https://softwareengineering.stackexchange.com/questions/99894/why-没有-http-have-post-redirect


开始讨论的旧方法:

您的问题似乎是您围绕整个数据字符串包装的encodeURIComponent()函数。这会将 & 符号替换为 &amp; 值。如果您在浏览器开发人员控制台中调试它,您将看到它未被识别为请求中的表单数据。您应该只转义您正在填写的变量。

顺便说一句:当你使用GET时,这也应该是有问题的。

这或多或少是我尝试过的,它通过 POST 发送数据。

    window.onload=function(){
        Lib.ajaxAlertFunction( '/test/target.php', 0, 0, 'Fantastic - data is being sent via POST! Amazeballs!', 0, 0 );
    };

    var Lib={}; /* Because I don't have the rest of `Lib` at my disposal */
    Lib.ajaxAlertFunction = function ( senturl, autoClose, closeButton, message, redirect, redirectTo ) {   
        var ajax;/* renamed only for brevity */
        try {
            ajax = new XMLHttpRequest();
        } catch (e) {
            try {
                ajax = new ActiveXObjext("Msxml2.XMLHTTP");
            } catch (e) {
                try {
                    ajax = new ActiveXObjext("Microsoft.XMLHTTP");
                } catch (e) {
                    alert ("Your browser can't handle the truth!");
                    return false;
                }
            }
        }
        if ( !senturl ) return false;
        else {
            var data =  "autoClose=" + autoClose + "&closeButton=" + closeButton + "&message=" + message + "&redirect=" + redirect + "&redirectTo=" + redirectTo;
        }

        ajax.onreadystatechange = function() {
            if( ajax.readyState == 4 && ajax.status == 200 ) {
                /*
                document.getElementById('outerFrame').innerHTML += ajax.responseText;
                newAlertLayer = document.getElementById('alertLayer');
                var arr = newAlertLayer.getElementsByTagName('script')
                for ( var n = 0; n < arr.length; n++ ) {
                    eval( arr[n].innerHTML );
                }
                */
                console.log( ajax.responseText );
            }
        }
        ajax.open( 'POST', senturl, true );
        ajax.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded' );
        ajax.send( data );
    }

为了测试,/test/target.php很简单:

<?php
    exit( print_r($_POST,true) );
?>

和响应:

Array
(
    [autoClose] => 0
    [closeButton] => 0
    [message] => Fantastic - data is being sent via POST! Amazeballs!
    [redirect] => 0
    [redirectTo] => 0
)

如果它有帮助,这是我在测试中使用的一个基本的 ajax 函数,也许其中的某些东西可能会有用?

        function _ajax( url, options ){
            var factories=[
                function() { return new XMLHttpRequest(); },
                function() { return new ActiveXObject('Msxml2.XMLHTTP'); },
                function() { return new ActiveXObject('MSXML2.XMLHTTP.3.0'); },
                function() { return new ActiveXObject('MSXML2.XMLHTTP.4.0'); },
                function() { return new ActiveXObject('MSXML2.XMLHTTP.5.0'); },
                function() { return new ActiveXObject('MSXML2.XMLHTTP.6.0'); },
                function() { return new ActiveXObject('Microsoft.XMLHTTP'); }
            ];
            /* Try each factory until we have a winner */
            for( var i=0; i < factories.length; i++ ) {
                try { var req = factories[ i ](); if( req!=null ) { break; } }
                catch( err ) { continue; }
            };
            var method=options.hasOwnProperty('method') ? options.method.toUpperCase() : 'POST';
            var callback=options.hasOwnProperty('callback') ? options.callback :false;
            if( !callback ){
                alert( 'No callback function assigned - a callback is required to handle the response data' );
                return false;
            }
            var headers={
                'Accept': "text/html, application/xml, application/json, text/javascript, "+"*"+"/"+"*"+"; charset=utf-8",
                'Content-type': 'application/x-www-form-urlencoded',
                'X-Requested-With': 'XMLHttpRequest'
            };
            /* The main parameters of the request */
            var params=[];
            if( options.hasOwnProperty('params') && typeof( options.params )=='object' ){
                for( var n in options.params ) params.push( n + '=' + options.params[n] );
            }
            /* Additional arguments that can be passed to the callback function */
            var args=options.hasOwnProperty('args') ? options.args : options;
            /* Assign callback to handle response */
            req.onreadystatechange=function(){
                if( req.readyState==4 ) {
                   if( req.status==200 ) options.callback.call( this, req.response, args );
                   else console.warn( 'Error: '+req.status+' status code returned' );
                }
            }
            /* Execute the request according to desired method */
            switch( method ){
                case 'POST':
                    req.open( method, url, true );
                    for( header in headers ) req.setRequestHeader( header, headers[ header ] );
                    req.send( params.join('&') );
                break;
                case 'GET':
                    req.open( method, url+'?'+params.join('&'), true );
                    for( header in headers ) req.setRequestHeader( header, headers[ header ] );
                    req.send( null );
                break;  
            }
        }

/* to use */
_ajax.call( this, '/test/target.php',{ callback:console.info, method:'post',params:{'field':'value','field2':'value2'} } );

调用 ajaxRequest 时,url 的末尾必须有一个"/"(例如,如果您没有指定/index.php 文件(。

我正在使用"/Modules/AlertLayer">

,并更改为"/Modules/AlertLayer/"已经解决了这个问题!