Общение с сервером через JavaScript - Часть 1

Общение с сервером через JavaScript - Часть 1

November 13, 2018

Доброго времени суток! Сегодня мы поговорим о разных методах взаимодействия с сервером, т.е. отправкой запросов, получением данных и т.д.

Для примера я буду брать такую структуру файлов:


Fetch

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

Для примера попробуем запросить файл file.json, лежащий в той же папке что и app.js:

fetch('./file.json').then(
 res => res.json()).then(
   json => console.log(json)
 )

Сначала мы используем функцию fetch(), далее идёт коллбек где мы обрабатываем GET запрос в json тип ( можно также и в обычный текст), и следующий коллбек уже выводит наш обработанный json.

Сам file.json выглядит вот так:

{
 "something kinda json file": "true",
 "one more prop": "I dont care"
}

Вот что у нас выводит при запросе file.json (cорри за тафтологию):

Object {
"something kinda json file": "true",
"one more prop": "I dont care"
}

Результат возвращается в виде объекта, а не просто строки, следовательно можно юзать свойства и по ним доставать значения.

Как я упомянул ранее, можно и получать обычный текст. Почти всё тоже самое, но json заменяем на text():

fetch('./file.txt').then(
 res => res.text()).then(
   text => console.log(text)
 )

Заглядываем в консоль и видим:

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do 
eiusmod tempor incididunt ut...

Также у Fetch есть всякие другие плюшки в виде заголовков, параметров, но мы пропустим это, т.к. не хватит рассказать о других.

XHR (XMLHttpRequest)

Объект XMLHttpRequest (или, как его кратко называют, «XHR») дает возможность из JavaScript делать HTTP-запросы к серверу без перезагрузки страницы.

Несмотря на слово «XML» в названии, XMLHttpRequest может работать с любыми данными, а не только с XML.

Из "Основы XMLHttpRequest"

Сначала нам нужно создать новый запрос через оператор new, как при классах. Далее мы выбираем тип запроса, в нашем случае это GET:

let xhr = new XMLHttpRequest();
xhr.open('GET', 'file.json', true);
xhr.responseType = "json";
xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
xhr.send();

В функции open первым аргументом выступает метод запроса, вторым файл, и третьим использовать ли ассинхрон - да, т.к. синхрон является устаревшим, о чём сообщают многие браузеры. После этого мы отсылаем наш запрос.

Ассинхрона можно добиться путём управления событием onreadystatechange:

xhr.onreadystatechange = function() {
   if (this.readyState === this.DONE){
     console.log('Статус: ' + this.status + ' ' + this.statusText);
     console.log(this.response);
     console.log('Тип отклика: ' + xhr.getResponseHeader('Content-Type'));
   }
}

У xhr появляется очень много свойств: readyState, status, responseText, statusText и т.д. Все свойства и события вы можете посмотреть в консоли:

Тут тоже много всего, но разберём по порядку.

status - статус код файла, 200 и более - успех (файл получен), 400 и более - ошибка (файл не получен).

setRequestHeader - установка заголовков запроса, например Content-Type. Со всеми заголовками можно ознакомиться в этой статье

responseURL - то откуда пришёл наш файл

statusText - более понятное обозначение status например Not Found или OK

response / responseText - похожие вещи, собственно отклик сервера в виде файла или текста. responseText используется только как текст, а response для любого типа файлов, например JSON

readyState - текущее состояние запроса. Всего 5 состояний: UNSENT, OPENED, HEADERS_RECEIVED, LOADING, DONE. Подробнее можно почитать здесь

onreadystatechange - событие, которое срабатывает при изменении состоянии запроса, например когда запрос прислан и имеет readyState=DONE.

responseType - тип отклика. Кстати эти же типы применимы и к fetch. По умолчанию не выставлен, есть несколько типов: json, document, text, arraybuffer, blob

getResponseHeader - информация о заголовке отклика. Обычно это тип отлика и его кодировка. К примеру: application/json; charset=UTF-8

Также есть ещё несколько событий и свойств, которые мы не будем затрагивать т.к. они используются реже.

jQuery AJAX

Понятно из названия, что нам пригодится jQuery.

AJAX - это набор инструментов для работы сервером (впрочем и XHR и Fetch тоже), расшифровывается как Async JavaScript And XML.

В jQuery существует функция $.ajax(). Всё довольно просто - в аргументах у нас объект с набором свойств. Для разнообразия попробуем XML, поэтому нам нужна функция для преобразования в строковый формат, потому что если этого не сделать, то мы получим объект XMLDocument, а не сам код.

xmlToStr = xml => {
 let str = new XMLSerializer().serializeToString(xml);
   return str;
}
$.ajax({
 url: './file.xml',
 beforeSend: () => {console.log('Prepare to get file.json')},
 method: 'GET',
 isLocal: true,
 dataType: 'xml',
 contentType: 'application/xml',
 statusCode: {
   200: () => {console.log('Everything is ok')},
   404: () => {console.log('Oops! Not found')}
 }
}).done(data => console.log(xmlToStr(data))).fail(() => console.error('Something bad happened.'))

И на выходе мы получаем:

Prepare to get file.json

<tag1>
  <tag2/>
</tag1>

Everything is ok

Данная конструкция сильно похожа на fetch, потому что она тоже асинхронна.

url - тоже что и responseURL в XHR

beforeSend - событие, до того как запрос отправлен

method - HTTP метод, например GET, POST, PUT и т.д. Подробнее о методах здесь

isLocal - мы используем файл на нашем компьютере, а не с сервера, поэтому true

statusCode - набор кодов ответа (200, 404), которые можно обработать

.done() - коллбек при завершении отправки

.fail() - коллбек при ошибке

contentType - тип контента, например application/json

dataType - тип данных: html / xml / json / script и т.д.

JSONP

JSONP - это метод получения JSON через тег <script>.

Сначала мы создаём тег скрипта, затем мы привязываем другой js файл, в котором лежат JSON данные, далее мы кладём скрипт в голову.

Пример кода:

app.js

addScript = src => {
 const elem = document.createElement("script");
 elem.src = src;
 document.head.appendChild(elem);
}
foo = data => {
 let jsonData = JSON.parse(data);
 console.log((jsonData));
}
addScript('json.js');

json.js

foo(`{
 "something kinda json file": "true",
 "one more prop": "I dont care"
}`)

Функция foo вытаскивает данные из симуляции JSON'а. JSON мы как раз-таки оборачиваем в строку через foo, чтобы потом вытащить данные.

Заключение

Мы рассмотрели наиболее популярные и простые методы взаимодействия с сервером через браузерный JavaScript. В скором будущем выйдет вторая часть, где мы рассмотрим Axios, Websocket и Soap.

Report Page