-1

这个问题过去可能被问过一百万次,但我还没有找到解决方案。所以我又问了一遍,希望得到一个不那么激进的答案,比如“看看别的地方”或“不要重复问题”。如果读者有输入上述任何句子或类似句子的冲动,我只能要求读者不要这样做,并完全忽略这篇文章。任何帮助是极大的赞赏。

问题

在我的程序中,AJAX 脚本与 PHP 脚本进行通信。没有语法错误。AJAX 接收responseText井并将其发出警报。

alert(request.responseText); //this works as desired

但未能将其返回到另一个函数。

return(request.responseText); //this actually returns undefined

完整的代码 客户端文件

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>test</title>
<script type="text/javascript" language="javascript" src="ajax.js"></script>
<script type="text/javascript" language="javascript">

    function createXMLHttp()
    {
        var xmlHttp = null; 
        if(window.XMLHttpRequest)
        {
            xmlHttp = new XMLHttpRequest();
        }
        else if(window.ActiveXObject)
        {   
            xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
        }
        return xmlHttp;
    }

    function ajax_phprequest(data, php_file)
    {
        var request =  createXMLHttp();
        request.open("POST", php_file, true);
        request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        request.send(data);
        request.onreadystatechange = function() 
        {
            if (request.readyState == 4)
            {
                document.write(request.responseText);
                return request.responseText; //changed from return(request.responseText;);
            }
        }
    }

    function foo()
    {
        alert(ajax_phprequest("user=defuser&pass=123456","auth.php"));
    }
</script>
</head>
    <input type="button" id="somebutton" value="Call foo()" onclick="foo();" />
<body>
</body>
</html>

完整的代码 auth.php 文件

<?php
    $user;
    $pass;
    if (isset($_POST['user']))  $user = $_POST['user'];
    else
    {
        echo 'err_u_Username is not specified';
        exit();     
    }
    if (isset($_POST['pass']))  $pass = $_POST['pass'];
    else
    {
        echo 'err_p_Password is not specified';
        exit();
    }
    if ($user = 'defuser' && $pass = '123456') echo ('That\'s right!');
    else echo ('That\'s not right!');
?>

这可以通过将代码包含在与文档相同的文件中轻松解决。但我希望从不同的文件中调用该函数,然后将其返回到具有的文件foo()或文档中。简单地说,我希望 AJAX 函数返回 responseText 而不会每次都给出“未定义”。如果这与同步有关:我想知道针对此问题的任何解决方法。

4

2 回答 2

2

已经提到了它的要点,但我想更深入地解释为什么这不起作用。

您有以下代码:

request.onreadystatechange = function() 
{
    if (request.readyState == 4)
    {
        document.write(request.responseText);
        return(request.responseText);
    }
}

基本上,您将onreadystatechange事件设置为匿名函数的值。在那个匿名函数中,您正在返回一个值,该值不会返回给 的调用者ajax_phprequest(),而是返回给匿名函数的调用者,它是事件系统,不太关心返回什么值。

之所以会这样,是因为这一切都是异步发生的。换句话说,你打电话ajax_phprequest(),那一刻发生的一切都发生在屏幕后面。用户可以像什么都没发生一样继续工作。但是,在后台请求并希望返回 php 文件。发生这种情况时,您可以使用内容,但是您调用的那一刻ajax_phprequest()早已过去。

正确的方法是使用回调函数。它可能看起来像这样:

function ajax_phprequest(data, php_file, callback)
{
    var request =  createXMLHttp();
    request.open("POST", php_file, true);
    request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    request.send(data);
    request.onreadystatechange = function() 
    {
        if (request.readyState == 4)
        {
            document.write(request.responseText);
            callback(request.responseText);
        }
    }
}

function foo()
{
    ajax_phprequest("user=defuser&pass=123456","auth.php", function (text)
    {
        alert(text);
    });
}
于 2012-04-23T11:09:25.610 回答
1

那是因为调用是 ASYNCHRONOUS ,所以你不能以通常的方式从堆栈返回,即alert(ajax_phprequest("user=defuser&pass=123456","auth.php"));在返回 ajax 响应之前评估你的......你需要使用回调:

function callback( text ){
    // something
}

...
if (request.readyState == 4){
    callback( request.responseText );
}
于 2012-04-23T10:59:23.737 回答