QA@IT
«回答へ戻る

回答を投稿

非同期モードなのでサーバーからレスポンスが戻る前に戻り値(document)を参照したた
めundefined(未定義値)が返って来たのだとおもいます。

そうではなくて、2 つめのコードが動かないのは、flied_onion さんが最初のレスで指摘されたように「xhr.onload のところに書いているreturnはあくまで xhr.onloadのreturnですのでxhrStartの戻り値にはなりません。」ということだからでしょう。

参考にされていた MDN の記事の一番最後のコードのように callback を利用してはいかがでしょう? 質問者さんのケースですと以下のような感じでしょうか? (検証してません。あくまで感じですので参考にとどめてください。)

function xhrStart(method, url, data, callback) {
    var xhr = new XMLHttpRequest();
    xhr.onload = function () {
        callback(xhr.response);
    }
    xhr.open(method, 'http://allow-any-origin.appspot.com/' + url);
    xhr.responseType = "document";
    xhr.send(data);
}

xhrStart('GET', 'http://www.yahoo.co.jp/', null, callback1);

function callback1(dom) {
    var element = dom.getElementById("toptxt");
    console.log(element.innerHTML);
    var childElement = element.getElementsByTagName("a");
    console.log(childElement[0].href);
    xhrStart('GET', childElement[0].href, null, callbaxk2);
}

function callback2(dom) {
    var innerElement = dom.getElementsByTagName("a");
    console.log(innerElement[Math.floor(Math.random() * innerElement.length)].href);
    xhrStart('GET', innerElement[Math.floor(Math.random() * innerElement.length)].href, null, callback3);
}

function callback3(dom) {
    var innerInnerElement = dom.getElementsByTagName("a");
    console.log(innerInnerElement[Math.floor(Math.random() * innerInnerElement.length)].href);
}

# allow-any-origin.appspot.com というのを調べましたが、個人が立てたプロキシです。応答ヘッダに Access-Control-Allow-Origin: * をつけて返してくれる仕組みになっているようです。いつサービスが終了するか分からないので、業務目的には使わないほうが良いかと思います。

> 非同期モードなのでサーバーからレスポンスが戻る前に戻り値(document)を参照したた
> めundefined(未定義値)が返って来たのだとおもいます。

そうではなくて、2 つめのコードが動かないのは、flied_onion さんが最初のレスで指摘されたように「xhr.onload のところに書いているreturnはあくまで xhr.onloadのreturnですのでxhrStartの戻り値にはなりません。」ということだからでしょう。

参考にされていた MDN の記事の一番最後のコードのように callback を利用してはいかがでしょう? 質問者さんのケースですと以下のような感じでしょうか? (検証してません。あくまで感じですので参考にとどめてください。)

```
function xhrStart(method, url, data, callback) {
    var xhr = new XMLHttpRequest();
    xhr.onload = function () {
        callback(xhr.response);
    }
    xhr.open(method, 'http://allow-any-origin.appspot.com/' + url);
    xhr.responseType = "document";
    xhr.send(data);
}

xhrStart('GET', 'http://www.yahoo.co.jp/', null, callback1);

function callback1(dom) {
    var element = dom.getElementById("toptxt");
    console.log(element.innerHTML);
    var childElement = element.getElementsByTagName("a");
    console.log(childElement[0].href);
    xhrStart('GET', childElement[0].href, null, callbaxk2);
}

function callback2(dom) {
    var innerElement = dom.getElementsByTagName("a");
    console.log(innerElement[Math.floor(Math.random() * innerElement.length)].href);
    xhrStart('GET', innerElement[Math.floor(Math.random() * innerElement.length)].href, null, callback3);
}

function callback3(dom) {
    var innerInnerElement = dom.getElementsByTagName("a");
    console.log(innerInnerElement[Math.floor(Math.random() * innerInnerElement.length)].href);
}
```

# allow-any-origin.appspot.com というのを調べましたが、個人が立てたプロキシです。応答ヘッダに Access-Control-Allow-Origin: * をつけて返してくれる仕組みになっているようです。いつサービスが終了するか分からないので、業務目的には使わないほうが良いかと思います。