我遇到一个问题,我需要检索XML文件的内容,然后将其填充到下拉框中。这应该很容易,但是此XML文件的链接通常会发生变化。
为此,我的解决方法是获取您下载xml文件的页面,找到链接,然后使用该链接获取xml文件。 AKA这将需要2个Http请求。
我的代码是:
var data = null;
var Doc = new Document();
var element;
var link = "";
var xmlDoc;
var xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function() {
if(this.readyState === 4 && link === "") { //if we havent gotten the link yet, get it
Doc = this.response; //get the HTML document where the link is
element = Doc.getElementsByClassName("failoverLink")[0]; //get the element with the link
link = element.href; //get the link
console.log(link); // IMPORTANT: when running the script, this actually returns the link in this context
}
else
{
if(this.readyState === 4) //now get the actual XML Document
{
xmlDoc = this.responseXML; //get the document
var txt = "<option></option>"; //construct the dropdown box
var i;
var x = xmlDoc.getElementsByTagName("Region"); //get all elements that we need for the dropdown
for(i=0; i<x.length; i++) {
txt += "<option>" + x[i].attributes.Name.value + "</option>";
}
document.getElementById("dropdown").innerHTML = txt; //insert it into the page
}
}
});
xhr.open("GET", "https://cors-anywhere.herokuapp.com/<link 1 of the parent document> replaced for privacy purposes");
xhr.responseType = "document";
xhr.send(data);
xhr.abort();
var newlink = "https://cors-anywhere.herokuapp.com/" + link;
xhr.open("GET", newlink);
xhr.responseType = "document";
xhr.overrideMimeType('text/xml');
xhr.send(data);
xhr.abort();
预期结果是实际获取XML文档。在开发人员控制台中可以正常工作!
但是,当尝试运行实际脚本时,它显示控制台中的链接很好,但是在事件侦听器函数的上下文之外,它仍然为null。
有人有什么想法吗?
更正:每当我在控制台中逐个运行每个命令时。有用。每当我一起运行它们时,它都表示为空。我猜我必须以某种方式等待它完成?如果可以,怎么办?
答案 0 :(得分:0)
所以我最终解决了自己的问题。问题是,事件侦听器在第二次调用之前没有第一次完成。这是我修复它的方法。
xhr1.addEventListener("readystatechange", function() {
if(xhr1.readyState === 4) {
Doc = xhr1.response;
element = Doc.getElementsByClassName("failoverLink")[0];
link = element.href;
console.log(link);
xhr2.addEventListener("readystatechange", function() {
if(this.readyState === 4)
{
xmlDoc = this.responseXML;
var txt = "<option></option>";
var i;
var x = xmlDoc.getElementsByTagName("Region");
for(i=0; i<x.length; i++) {
txt += "<option>" + x[i].attributes.Name.value + "</option>";
}
document.getElementById("dropdown").innerHTML = txt;
}
});
var newlink = "https://cors-anywhere.herokuapp.com/" + link;
xhr2.open("GET", newlink);
xhr2.responseType = "document";
xhr2.overrideMimeType('text/xml');
xhr2.send(data);
}
});
是的,我最终不得不创建两个不同的XHR对象...但是我想它会做到的。