Для отправки сервером ответа клиенту применяется класс HttpResponse. Этот класс реализует интерфейс класса IOSink и поэтому представляет поток для записи.
Для записи данных в поток ответа класс предсотавляет ряд методов:
write(Object? object)
: записывает в поток произвольный объект
writeAll(Iterable objects, [String separator = ""])
: записывает в поток набор объектов
writeCharCode(int charCode)
: записывает в поток числовой код символа
writeln([Object? object = ""])
: записывает в поток произвольный объект с переводом строки
Чтобы закрыть поток ответа и отправить данные клиенту применяется метод close()
Для получения потока ответа применяется свойство response объекта HttpRequest:
import 'dart:io'; void main() async { var server = await HttpServer.bind(InternetAddress.anyIPv6, 8888); print("Сервер запущен..."); await server.forEach((HttpRequest request) { final response = request.response; // получаем объект ответа HttpResponse response.write("Привет мир"); response.write("Пока мир"); response.close(); // отправляем ответ }); }
В данном случае в поток ответа пишем две строки с помощью метода write()
. Мы можем таким образом последовательно добавлять в поток различные данные.
Если мы обратимся к приложению в браузере, то увидим, что данные сливаются. То есть данные в ответе идут таким образом, как они добавлены. Но в данном случае мы могли бы
добавить символ перевода строки в саму строку или использовать метод writeln
для добавления перевода строки:
response.writeln("Привет мир"); response.writeln("Пока мир");
Для установки заголовков в класссе HttpResponse определено свойство headers:
HttpHeaders get headers;
Это свойство представляет тип HttpHeaders, который предоставляет ряд методов для управления заголовками. В частности, для добавления заголовка применяется метод add(), в который передается имя заголовка и его значение:
import 'dart:io'; void main() async { var server = await HttpServer.bind(InternetAddress.anyIPv6, 8888); print("Сервер запущен..."); await server.forEach((HttpRequest request) { final response = request.response; // добавляем заголовок response.headers.add("Secret", "12345"); response.write("Hello METANIT.COM"); response.close(); }); }
Здесь добавляем произвольный заголовок "Secret" со значением "12345":
response.headers.add("Secret", "12345");
И через инструменты браузера для разработчиков мы можем увидеть данный заголовок
Также для установки заголовка можно применять метод set(), в который передаются название заголовка и его значение:
response.headers.set("Secret", "12346");
Для установки наиболее используемых заголовков класс HttpHeaders определяет ряд свойств:
contentLength: устанавливает заголовок "Content-Length" (размер ответа)
contentType: устанавливает заголовок "Content-Type" (тип содержимого) и предоставляет тип ContentType
date: устанавливает заголовок "date" (дата запроса) и представляет тип DateTime?
expires: устанавливает заголовок "expires" и представляет тип DateTime?
host: устанавливает заголовок "host"
ifModifiedSince: устанавливает заголовок "If-Modified-Since" и представляет тип DateTime?
port: устанавливает заголовок "port"
Использование свойств:
import 'dart:io'; void main() async { var server = await HttpServer.bind(InternetAddress.anyIPv6, 8888); print("Сервер запущен..."); await server.forEach((HttpRequest request) { final response = request.response; // добавляем заголовоки response.headers.contentType = ContentType("text", "plain"); response.headers.host = "metanit.com"; response.headers.date = DateTime.now(); response.write("Hello METANIT.COM"); response.close(); }); }
Для установки заголовка ContentType применяется объект ContentType, в конструктор которого передается тип содержимого. Причем первый параметр конструктора представляет основной типа содержимого, а второй параметр - второстепенный тип содержимого:
response.headers.contentType= ContentType("text", "plain");
В нашем случае тип содержимого должен представлять "text\plain" - здесь "text" представляет основной тип содержимого, а "plain" - дополнительный.
Поскольку при добавлении стандартного заголовка легко допустить ошибку (особенно при длинном названии заголовка), то для упрощения установки заголовков класс HttpHeaders предоставляет ряд статических свойств. Отмечу основные:
acceptCharsetHeader
: представляет заголовок "accept-charset"
acceptEncodingHeader
: представляет заголовок "accept-encoding"
acceptHeader
: представляет заголовок "accept"
acceptLanguageHeader
: представляет заголовок "accept-language"
acceptRangesHeader
: представляет заголовок "accept-ranges"
ageHeader
: представляет заголовок "age"
allowHeader
: представляет заголовок "allow"
authorizationHeader
: представляет заголовок "authorization"
cacheControlHeader
: представляет заголовок "cache-control"
connectionHeader
: представляет заголовок "connection"
contentEncodingHeader
: представляет заголовок "content-encoding"
contentLanguageHeader
: представляет заголовок "content-language"
contentLengthHeader
: представляет заголовок "content-length"
contentRangeHeader
: представляет заголовок "content-range"
contentTypeHeader
: представляет заголовок "content-type"
cookieHeader
: представляет заголовок "cookie"
dateHeader
: представляет заголовок "date"
etagHeader
: представляет заголовок "etag"
expiresHeader
: представляет заголовок "expires"
hostHeader
: представляет заголовок "host"
lastModifiedHeader
: представляет заголовок "last-modified"
locationHeader
: представляет заголовок "location"
pragmaHeader
: представляет заголовок "pragma"
refererHeader
: представляет заголовок "referer"
serverHeader
: представляет заголовок "server"
setCookieHeader
: представляет заголовок "set-cookie"
userAgentHeader
: представляет заголовок "user-agent"
varyHeader
: представляет заголовок "vary"
viaHeader
: представляет заголовок "via"
warningHeader
: представляет заголовок "warning"
wwwAuthenticateHeader
: представляет заголовок "www-authenticate"
Применение некоторых свойств:
import 'dart:io'; void main() async { var server = await HttpServer.bind(InternetAddress.anyIPv6, 8888); print("Сервер запущен..."); await server.forEach((HttpRequest request) { final response = request.response; // добавляем заголовки response.headers.add(HttpHeaders.contentTypeHeader, "text/plain; charset=utf-8"); response.headers.add(HttpHeaders.hostHeader, "metanit.com"); response.headers.add(HttpHeaders.dateHeader, DateTime.now()); response.write("Hello METANIT.COM"); response.close(); }); }
Код html представляет строку, которая содержит элементы html. Однако, чтобы ответ сервера интерпретировался как код html, необходимо для заголовка ContentType
установить значение "text/html" (бех установки данного заголовка код html будет рассматриваться как простоя строка):
import 'dart:io'; void main() async { var server = await HttpServer.bind(InternetAddress.anyIPv6, 8888); print("Сервер запущен..."); await server.forEach((HttpRequest request) { final response = request.response; response.headers.contentType= ContentType("text", "html"); response.write("<h1>Hello METANIT.COM</h1><h3>Hello from Dart</h3>"); response.close(); }); }
В качестве ответа отправляет html-код, который содержит два элемента - два заголовка:
response.write("<h1>Hello METANIT.COM</h1><h3>Hello from Dart</h3>");
И при обращении к приложению браузер отобразит нам веб-страницу с двумя элементами: