从函数中作为返回值返回xmlhttp的responseText

8

我是JavaScript和PHP的新手,我的目标是:将XMLHttpRequest的responseText返回字符串作为函数返回值。这样我就可以使用innerText或innerHTML方法。

HTML代码:

<script>
function loadXMLDoc(myurl){
    var xmlhttp;
    if (window.XMLHttpRequest){
        xmlhttp=new XMLHttpRequest();}
    else{
        xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");}

     xmlhttp.onreadystatechange=function(){
         if (xmlhttp.readyState==4 && xmlhttp.status==200){
              xmlhttp.responseText;}
     }

    xmlhttp.open("GET",myurl,true);
    xmlhttp.send();
}
</script>

1
不要使用 innerText:它是微软专有成员,虽然 Chrome 支持它,但 Firefox 不支持。如果 textContent 不受支持(IE8 及更早版本),则将其用作备用方案。 - MaxArt
2个回答

11

你做不到。

代码既不是同步运行的,也不会将任何内容returnloadXMLDoc,而是返回给匿名函数,该匿名函数是onreadystatechange处理程序。

最好的办法是传递一个回调函数。

function loadXMLDoc(myurl, cb) 
{
   // Fallback to Microsoft.XMLHTTP if XMLHttpRequest does not exist.
   var xhr = (window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP"));

    xhr.onreadystatechange = function()
    {
        if (xhr.readyState == 4 && xhr.status == 200)
        {
            if (typeof cb === 'function') cb(xhr.responseText);
        }
    }

   xhr.open("GET", myurl, true);
   xhr.send();

}

然后像这样调用它

loadXMLDoc('/foobar.php', function(responseText) {
    // do something with the responseText here
});

给jAndy:我想让loadXMLdoc函数本身作为返回值,这样我就可以创建一个简单的函数来设置元素的innerText或innerHTML,这可能吗? - inogbox
只要您的ajax请求以异步模式运行(这是极其推荐的),就不会出现这个问题。您可以手动将请求设置为“同步”,这意味着每次请求运行时都会锁定并冻结浏览器UI。您可以通过将.open()的第三个参数设置为false来实现此操作。 - jAndy
我的目标是使用异步模式,所以我必须创建处理程序来传递响应文本吗? - inogbox
为什么你的代码无法运行?即使我使用alert()函数,当我调用它时也没有返回任何东西。 - inogbox
@inogbox:我的代码无法运行?无论如何 - 在这种情况下,没有办法在异步请求中返回任何内容。您必须选择同步请求或使用回调方法,就像我演示的那样。 - jAndy
是的,我复制并粘贴了您的代码到我的代码编辑器中,并创建了一个执行loadXMLDoc的函数,然后在“//在此处对responseText进行操作”中添加了alert()函数,但什么也没有发生,我期望的消息框没有显示。您能告诉我出了什么问题吗? - inogbox

4

只需返回responseText属性或将其值分配给闭包中的变量。

返回一个值:

<script>
    function loadXMLDoc(myurl) {
        var xmlhttp;
        if (window.XMLHttpRequest) {
            xmlhttp = new XMLHttpRequest();
        } else {
            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        }

        xmlhttp.onreadystatechange = function () {
            if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                return xmlhttp.responseText;
            }
        }

        xmlhttp.open("GET", myurl, true);
        xmlhttp.send();
        return xmlhttp.onreadystatechange();
    }
</script>

使用闭包:

<script>
    var myValue = "",
        loadXMLDoc = function (myurl) {
            var xmlhttp;
            if (window.XMLHttpRequest) {
                xmlhttp = new XMLHttpRequest();
            } else {
                xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
            }

            xmlhttp.onreadystatechange = function () {
                if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                    return xmlhttp.responseText;
                }
            }

            xmlhttp.open("GET", myurl, true);
            xmlhttp.send();
            myValue = xmlhttp.onreadystatechange();
        };
</script>

1
这在异步模式下不起作用。 - pimvdb
如果调用需要一个函数引用,则除了本地函数的其他内容之外,它不应该是异步的。 - austincheney
你是什么意思?这个请求是异步的,所以 return 不会返回实际的响应,因为它还没有被接收到。 - pimvdb
不是这样的。这就是我在 http://prettydiff.com/ 中在自己的软件中使用 AJAX 的方式。JavaScript 中没有任何异步操作,只是变体的外部访问 JavaScript 创造了异步操作的外观。 - austincheney
2
你真的必须使用同步模式进行ajax(.open(...,false)),否则return是虚假的。在这里查看您的代码:http://jsfiddle.net/HApG3/。 - pimvdb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接