Как отредактировать документ полученный через XMLHttpRequest?

При получении HTML-странички через AJAX - как работать с ее элементами, а не с текстом разметки?

Например, удалить из полученной страницы <head>, добавить класс ее элементу <h1>, или вставить еще один элемент в <body>.


Ответы (2 шт):

Автор решения: yar85

Можно установить свойство responseType объекта запроса в значение 'document' - тогда текст ответа сервера будет автоматически разобран в DOM, и с ним можно будет работать как с объектом документа:

const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://httpbin.org/html');
xhr.responseType = 'document'; 
xhr.onloadend = evt => {
  // результат берем из свойства `responseXML` (в случае неудачи, там будет `null` вместо объекта `Document`)
  const doc = evt.currentTarget.responseXML; 
  if (!doc) return console.error('Карррамба!'); 

  // удаляем из документа `head`
  doc.head.remove(); 
  // добавляем класс уже существующему элементу 
  doc.querySelector('h1').classList.add('foo'); 
  // вставляем новый элемент в `body`
  const newEl = doc.createElement('p'); 
  newEl.textContent = 'Привет, StackOverflow!'; 
  doc.body.insertAdjacentElement('afterBegin', newEl); 

  console.log(doc.documentElement.outerHTML); 
}; 
xhr.send(); 

→ Ссылка
Автор решения: yar85

Если автоматический парсинг ответа сервера (установкой responseType) по каким-то причинам неудобен, то можно и самостоятельно разобрать текст разметки в DOM - используя DOMParser:

const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://httpbin.org/html');
xhr.onloadend = evt => {
  const parser = new DOMParser(); 
  let doc; 
  // в случае неудачи при разборе разметки, будет брошена ошибка (TypeError)
  try {
    doc = parser.parseFromString(evt.currentTarget.responseText, 'text/html'); 
  } catch (err) { return console.error('Карррамба!'); }

  // удаляем из документа `head`
  doc.head.remove(); 
  // добавляем класс уже существующему элементу 
  doc.querySelector('h1').classList.add('foo'); 
  // вставляем новый элемент в `body`
  const newEl = doc.createElement('p'); 
  newEl.textContent = 'Привет, StackOverflow!'; 
  doc.body.insertAdjacentElement('afterBegin', newEl); 

  console.log(doc.documentElement.outerHTML); 
}; 
xhr.send(); 

Этот способ по-моему единственно возможный при выполнении запроса через fetch, а не XMLHttpRequest.

→ Ссылка