Возврат HTML с помощью fetch()

Я пытаюсь получить файл и вернуть его HTML. Однако это не так просто, как я себе представлял.

    fetch('/path/to/file')
    .then(function (response) {
      return response.body;
    })
    .then(function (body) {
      console.log(body);
    });

Это возвращает объект с именем ReadableByteStream. Как мне использовать это для захвата содержимого HTML-файла?

Если я изменю содержимое /path/to/file на строку JSON и изменю приведенное выше на:

    fetch('/path/to/file')
    .then(function (response) {
      return response.json();
    })
    .then(function (json) {
      console.log(json);
    });

... он правильно возвращает JSON. Как получить HTML?


person ditto    schedule 14.04.2016    source источник
comment
это вызывает опасения: что вы собираетесь делать с этим HTML? потому что я надеюсь, что он не введет его в мой активный документ. Вместо этого запросите данные в форме JSON, а затем создайте DOM вокруг этого на стороне клиента, чтобы вы знали, что пользователь не загружает потенциально взломанный и сверхнебезопасный слепой HTML.   -  person Mike 'Pomax' Kamermans    schedule 14.04.2016
comment
@Mike'Pomax'Kamermans Вы предполагаете, что HTML исходил от пользователя. Я возвращаю сгенерированный на стороне сервера HTML, чтобы воспользоваться преимуществами строго типизированных представлений, созданных с помощью строго типизированного языка сервера.   -  person Louise Eggleton    schedule 09.07.2019
comment
А вы доверяете своему серверу? Я, конечно, не доверяю своему, у меня даже нет оборудования, на котором оно работает. Вместо того, чтобы запрашивать HTML, я искренне рекомендую использовать morphdom: пусть ваш сервер генерирует HTML, но затем сгенерируйте diff, который вы отправляете своему клиенту, и попросите его снова применить этот diff к активной DOM с morphdom. Меньшая полезная нагрузка, поэтому вещи более отзывчивы и безопаснее.   -  person Mike 'Pomax' Kamermans    schedule 09.07.2019
comment
@Mike'Pomax'Kamermans Поскольку JS запускается в консоли, не может ли пользователь в любом случае вводить что-либо в активный документ?   -  person Denis G. Labrecque    schedule 21.07.2020
comment
Не с включенным вменяемым CSP, нет. Они могут добавить его, но браузер откажется его запускать, поскольку он нарушает script-src правила CSP сервера.   -  person Mike 'Pomax' Kamermans    schedule 21.07.2020


Ответы (6)


Вам нужно использовать метод .text() вместо .json(). Это преобразует поток байтов в обычный текст, который может быть проанализирован браузером как HTML.

person bronzehedwick    schedule 14.04.2016

Вы можете загрузить html с помощью fetch, а затем проанализировать его с помощью DomParser API.

fetch('somePage.html')
    .then(function(response) {
        // When the page is loaded convert it to text
        return response.text()
    })
    .then(function(html) {
        // Initialize the DOM parser
        var parser = new DOMParser();

        // Parse the text
        var doc = parser.parseFromString(html, "text/html");

        // You can now even select part of that html as you would in the regular DOM 
        // Example:
        // var docArticle = doc.querySelector('article').innerHTML;

        console.log(doc);
    })
    .catch(function(err) {  
        console.log('Failed to fetch page: ', err);  
    });

person Vladimir Jovanović    schedule 12.06.2018
comment
не знал об этом, я использовал innerHTML - person Muhammad Umer; 07.04.2019
comment
Приятно, что ответ именно то, что я искал, хотя в вопросе не упоминалась запись в DOM. Также актуально: api.jquery.com/load - person caffeinum; 25.07.2019
comment
@caffeinum - спасибо! Когда вы получаете внешнюю html-страницу, она будет в текстовом формате, и вы не сможете сделать с ней ничего значимого. ИМХО, естественным следующим шагом было что-то сделать с этим документом, и для этого мы должны разобрать этот текст как DOM. В этот момент мы можем выбрать и манипулировать этим документом. Я специально не хотел упоминать jQuery, потому что будущее за ванильным JS. Мы все должны перейти к этому, если мы еще этого не сделали. - person Vladimir Jovanović; 29.07.2019
comment
поэтому скрипт, прикрепленный к этому файлу, будет работать?? - person Muhammad Saquib Shaikh; 16.11.2020

вы можете вернуть ответ с помощью .text(), а затем отобразить страницу в документе по своему усмотрению.

function fetchHtml() {
  fetch('./file.html')
  .then((response) => {
    return response.text();
  })
  .then((html) => {
    document.body.innerHTML = html     
  });
}
person mahmoud miz    schedule 05.04.2020

Использование Promise Chaining с .then() — это старый способ кодирования выборок и ответов. Более современным способом было бы использование async функций и await как показано ниже:

async function fetchMyDocument() {      
  try {
    let response = await fetch('/path/to/file.html'); // Gets a promise
    document.body.innerHTML = await response.text(); // Replaces body with response
  } catch (err) {
    console.log('Fetch error:' + err); // Error handling
  }
}

А что касается прямого ответа на вопрос, (как и любой другой ответ) .text() используется вместо .json() в ответе.

person FoxPaw    schedule 14.03.2021

Должен быть:

fetch('/path/to/file').then(function(response) {
    return response.text();
}).then(function(string) {
    console.log(string);
}).catch(function(err) {  
    console.log('Fetch Error', err);  
});
person Trần Nguyên Khuyến    schedule 03.10.2018

  • 1- вызовите функцию fetch и добавьте путь к странице.
  • 2- затем преобразуйте данные выборки в текст с помощью функции .text().
  • 3- затем append компонент страницы в родительский контейнер.

       async function getAbout() {


    await fetch('./component/about.html').then(res => res.text()).then(data => {
    page_2.innerHTML = data;

     }).then(() => {
       
         // after fetch write js code here  
     })}

  • для извлечения компонента не добавляйте теги <body> или <HTML> ‹ просто используйте другие теги, такие как <div> или другие теги.

  • для повышения производительности используйте async-await!.

person Omar bakhsh Available to work    schedule 01.07.2020