2010-04-10 3 views
1

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

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

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

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

Спасибо!

ответ

1

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

Вы также можете использовать метод toStaticHTML() IE8, но гаджет необходимо будет работать в режиме IE8.

+1

Спасибо! Я всегда забываю, что мне не нужно быть кросс-браузером в гаджетах, поэтому я могу использовать ActiveX. –

+0

@ m6a-uds: Это, вероятно, самое большое преимущество разработки гаджетов и самого большого подходящего использования для собственных функций IE. Некоторые из материалов, которые я встроил в гаджеты, не имели бы шансов работать в другом браузере :-) –

0

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

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

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

-1

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

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

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

@ Майкл: К сожалению, настольные гаджеты Windows запускаются в маленьких окнах Internet Explorer «Server», поэтому ваше решение Mozilla здесь не очень помогает :-) –

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.

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

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

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

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

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

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

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

+0

@Rajat: 'querySelector' недоступен в IE7, который установлен по умолчанию в Vista и, следовательно, хост для Windows Desktop Gadgets если IE8 не установлен, и гаджет определяет IE8 для заголовка 'X-UA-Compatible' в метатеге. 'getElementsByClassName' не поддерживается текущей версией IE. –

Смежные вопросы