从XMLHttpRequest中提取单个元素

时间:2010-04-10 18:00:03

标签: javascript ajax windows-desktop-gadgets

我实际上正在创建一个Sidebar Gadget(基于AJAX),我正在寻找一种从AJAX请求中提取单个元素的方法。

我发现的唯一方法就是做那样的事情:

var temp = document.createElement("div");
temp.innerHTML = HttpRequest.innerText;
document.body.appendChild(temp);
temp.innerHTML = document.getElementByID("WantedElement").innerText;

但它非常难看,我想直接从请求中提取WantedElement而不将其添加到实际文档中......

谢谢!

5 个答案:

答案 0 :(得分:1)

如果您掌控数据,那么您的方式可能是最好的方法。这里的其他答案有它们的好处,但它们都有相当缺陷。例如,querySelector()方法仅适用于在主机上以IE8模式运行的Windows桌面小工具。正则表达式对于解析HTML特别不可靠,不应使用。

如果您无法控制数据或数据未通过安全协议传输,您应该更关注安全而不是代码美学 - 您可能会对小工具和主机引入潜在的安全风险通过将未经过说明的HTML插入到文档中。由于小工具使用用户或管理员级别权限运行,因此明显的安全风险是不受信任的源/ MITM脚本注入,为恶意脚本留下一个漏洞,对其运行的计算机造成严重破坏。

一个可能的解决方案是使用htmlfile ActiveXObject:

function getElementFromResponse(divId)
{
    var h = new ActiveXObject("htmlfile");
    h.open();

    // disable activex controls
    h.parentWindow.ActiveXObject = function () {};

    // write the html to the document
    h.write(html);

    h.close();
    return h.getElementById("divID").innerText;
}

您也可以使用IE8的toStaticHTML()方法,但您的小工具需要在IE8模式下运行。

答案 1 :(得分:0)

一种选择是使用正则表达式:

var str = response.match(/<div id="WantedElement">(.+)<\/div>/);
str[0]; // contents of div

但是,如果您的服务器响应更复杂,我建议您使用JSON等数据格式作为响应。然后在客户端解析会更清晰。

答案 2 :(得分:0)

您可以将XMLHttpRequest中的响应附加到隐藏的div中,然后调用getElementById以获取所需的元素。稍后在完成后删除div。或者也许创建一个为您处理此问题的函数。

function addNinjaNodeToDOM(html) {
    var ninjaDiv = document.createElement("div");
    ninjaDiv.innerHTML = html;
    ninjaDiv.style.display = 'none';
    return ninjaDiv;
}

var wrapper = addNinjaNodeToDOM(HttpRequest.innerText);
var requiredNode = wrapper.getElementById("WantedElement");
// do something with requiredNode
document.body.removeChild(wrapper); // remove when done

将其附加到DOM的唯一原因是因为getElementById除非是DOM树的一部分,否则将无法工作。请参阅MDC

但是,您仍然可以在分离的DOM节点上运行选择器和XPath查询。这样可以避免让你将元素附加到DOM。

var superNinjaDiv = document.createElement('div');
superNinjaDiv.innerHTML = html;
var requiedNode = superNinjaDiv.querySelector("[id=someId]");

答案 3 :(得分:0)

我认为在这种情况下使用getElementById查找元素不是一个好方法。这是因为您必须采取额外的步骤才能使用它。您将元素包装在DIV中,注入DOM,使用getElementById查找元素,然后从DOM中删除注入的DIV。

DOM操作很昂贵,注入也可能导致不必要的回流。问题是你有一个document.getElementById而不是一个element.getElementById,它允许你在文档中进行查询而无需注入。

要解决这个问题,使用querySelector是一个明显的解决方案,它要容易得多。否则,我建议你使用getElementsByClassName,如果可以,你的元素是否定义了类。

getElementsByClassName在ELEMENT上定义,因此可以在不注入DOM的元素的情况下使用。

希望这有帮助。

答案 4 :(得分:-1)

通过AJAX请求传递HTML有点不寻常;通常,您传递一个客户端可以直接评估的JSON字符串,并使用该

话虽如此,我认为没有办法按照你想要的跨浏览器的方式解析javascript中的HTML,但是这是Mozilla衍生产品中的一种方式:

var r = document.createRange();
r.selectNode(document.body);
var domNode = r.createContextualFragment(HTTPRequest.innerText);