Извлечь один элемент из XMLHttpRequest - PullRequest
1 голос
/ 10 апреля 2010

Я на самом деле создаю гаджет для боковой панели (на основе AJAX) и ищу способ извлечь отдельный элемент из запроса AJAX.

Единственный способ, который я нашел, - сделать что-то подобное:

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

Но это довольно уродливо, я хотел бы извлечь WantedElement непосредственно из запроса, не добавляя его в фактический документ ...

Спасибо!

Ответы [ 5 ]

1 голос
/ 11 апреля 2010

Если вы контролируете данные, то, вероятно, лучший способ это сделать. Другие ответы здесь имеют свои преимущества, но также все они довольно несовершенны. Например, метод querySelector() доступен только для гаджетов Windows Desktop, работающих в режиме IE8 на хост-компьютере. Регулярные выражения особенно ненадежны для анализа HTML и не должны использоваться.

Если вы не контролируете данные или если данные не передаются по безопасному протоколу, вам следует больше заботиться о безопасности, чем об эстетике кода - возможно, вы представляете потенциальные угрозы безопасности для гаджета и хоста машина, вставив неанализованный HTML в документ. Поскольку гаджеты запускаются с привилегиями уровня пользователя или администратора, очевидная угроза безопасности заключается в внедрении сценария source / 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.

0 голосов
/ 12 апреля 2010

Я думаю, что использование getElementById для поиска элемента в этом случае не очень хороший подход. Это из-за дополнительных шагов, которые вы должны предпринять, чтобы использовать его. Вы оборачиваете элемент в DIV, внедряете в DOM, ищите свой элемент с помощью getElementById, а затем удаляете внедренный DIV из DOM.

Манипулирование DOM является дорогостоящим, и инъекция может также вызвать ненужное оплавление. Проблема в том, что у вас есть document.getElementById, а не element.getElementById, который позволил бы вам выполнять запрос без внедрения в документ.

Чтобы решить эту проблему, использование querySelector является очевидным решением, которое намного проще. Иначе, я бы предложил использовать getElementsByClassName, если вы можете и если ваш элемент имеет определенный класс.

getElementsByClassName определено в ELEMENT и, следовательно, может использоваться без внедрения элемента в DOM.

Надеюсь, это поможет.

0 голосов
/ 10 апреля 2010

Несколько необычно передавать HTML через AJAX-запрос; обычно вы передаете строку JSON, которую клиент может оценить напрямую, и работаете с этим

При этом я не думаю, что есть способ разбирать HTML в javascript так, как вы хотите, это кросс-браузер, но вот способ сделать это в производных Mozilla:

var r = document.createRange();
r.selectNode(document.body);
var domNode = r.createContextualFragment(HTTPRequest.innerText);
0 голосов
/ 10 апреля 2010

Вы можете добавить ответ из 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 .

Однако вы все еще можете запускать запросы селектора и XPath на отдельных узлах DOM. Это избавит вас от необходимости добавлять элементы в DOM.

var superNinjaDiv = document.createElement('div');
superNinjaDiv.innerHTML = html;
var requiedNode = superNinjaDiv.querySelector("[id=someId]");
0 голосов
/ 10 апреля 2010

Одним из вариантов будет использование регулярных выражений:

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

Однако, если ваш ответ сервера более сложный, я бы предложил вам использовать для ответа такой формат данных, как JSON . Тогда было бы намного чище разобрать на стороне клиента.

...