-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

これは、呼び出しが非同期であるため、通常の方法でスタックから戻ることができないためです。つまり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 に答える