【问题标题】:AJAX without jQuery is not sending POST data to PHP file没有 jQuery 的 AJAX 不会将 POST 数据发送到 PHP 文件
【发布时间】:2016-02-05 03:41:18
【问题描述】:

几天来,我一直在尝试让 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 天搜索的几种不同方法设置“数据”变量,但均未成功。

需要 $_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 中 NETWORK 选项卡的屏幕截图:

【问题讨论】:

  • 尝试从数据中删除encodeURIComponent....就像你说的,它会被截断 - 没有它似乎很好。
  • 我刚刚编辑了上面的代码以显示我最初开始使用的内容,然后再尝试使用 encodeURIComponent 和其他方法。仅使用连接在一起的字符串是我的问题开始的地方,我猜为什么我使用 GET 没有问题。

标签: javascript php ajax post


【解决方案1】:

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

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


开始讨论的旧方法:

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

顺便说一句:这在​​你使用 GET 时也应该有问题。

【讨论】:

  • 谢谢,不过我应该介绍更多我以前的工作。使用 encodeURICompenent() 是我尝试让它工作的最后努力之一。我从一个字符串开始,现在已编辑并显示在上面的代码中。如果其他一切看起来都正常,我应该查看哪些可能导致此问题的事物/条件(服务器设置等)?
  • 当我 alert(data) autoClose=1&closeButton=1&message=

    Test

    警报层模块的第三次测试时,我得到了这个结果。

    &redirect=0&redirectTo =0,我在发送 GET 时使用此行(并且它有效)。 ajaxRequest.open("GET", senturl + "?" + data, true);
  • 您是否使用 encodeURIComponent() 转义了变量中的值?不是整个字符串。但是你放入函数中的每一个变量。
  • 刚刚添加了一条注释行,其中包含我认为您所描述的我已经测试但失败的内容。
  • 谢谢!您一直在努力帮助我,这使我遇到了问题。我知道这会很简单,而且确实如此。 URL 必须以“/”结尾,并且我使用的是没有结尾反斜杠的“/Modules/AlertLayer”,因为它在我所做的所有其他事情中一直有效。感谢您的帮助!
【解决方案2】:

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

我使用的是“/Modules/AlertLayer”,改成“/Modules/AlertLayer/”解决了这个问题!

【讨论】:

    【解决方案3】:

    这或多或少是我尝试过的,它通过 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'} } );
    

    【讨论】:

    • 感谢您一直以来的帮助,我将使用您的示例来尝试解决这个问题,但是如果您使用了我的代码并证明它有效,那么我认为我忽略了其他地方的问题,但是我不知道如何追踪它。
    • 在您认为可能出现错误的各个点使用console.log并观察输出...
    猜你喜欢
    • 1970-01-01
    • 2012-04-08
    • 2014-04-01
    • 2017-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-09
    • 1970-01-01
    相关资源
    最近更新 更多