При создании веб-приложения на чистом Node.js вы могли использовать класс http,
как мы делали в Начинаем с Node.js.
Тогда мы использовали только объект response
, но если нас интересует сам запрос, тогда нужно взглянуть на
объект request
, который мы получаем в функции обратного вызова (callback, колбек).
В этом простом примере http-сервера на Node.js
выводятся некоторые значения из объекта запроса, который является
экземпляром класса http.ClientRequest.
examples/node/http_client_request.js
var http = require('http');
var port = 8081;
var s = http.createServer();
s.on('request', function(request, response) {
response.writeHead(200);
console.log(request.method);
console.log(request.headers);
console.log(request.url);
response.write('hi');
response.end();
});
s.listen(port);
console.log('Browse to http://127.0.0.1:' + port);
Я запустил приведенный выше скрипт с помощью команды node examples/node/http_client_request.js
,
он вывел: Browse to http://127.0.0.1:8081
, и я зашел по указанному адресу через мой обычный браузер.
И вот что было выведено в консоль:
GET
{ host: '127.0.0.1:8081',
connection: 'keep-alive',
'cache-control': 'max-age=0',
accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.94 Safari/537.36',
'accept-encoding': 'gzip, deflate, sdch',
'accept-language': 'en-US,en;q=0.8,he;q=0.6,ru;q=0.4' }
/
GET
{ host: '127.0.0.1:8081',
connection: 'keep-alive',
accept: '*/*',
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.94 Safari/537.36',
'accept-encoding': 'gzip, deflate, sdch',
'accept-language': 'en-US,en;q=0.8,he;q=0.6,ru;q=0.4' }
/favicon.ico
Сначала это меня слегка смутило. Почему у меня два GET-запроса? Но потом я кое-что вспомнил и, присмотревшись, все понял.
Первый запрос действительно был к /
(как вы сами можете увидеть - перед вторым GET-запросом), но затем браузер отправил
второй запрос к /favicon.ico
. Это автоматический запрос браузера, отправленный в надежде,
что он сможет поместить это маленькое изображение на вкладке, где я открыл страницу.
Я не хочу, чтобы в моем исследовании была лишная путаница, поэтому я перешел на команду curl
, которая доступна в Linux/Unix.
Попробуем еще раз:
Я запустил сервер:
$ node examples/node/http_client_request.js
Browse to http://127.0.0.1:8081
и открыл еще одно командное окно, где написал свой запрос:
$ curl http://127.0.0.1:8081/
Затем переключился на предыдущую консоль, чтобы посмотреть ответ:
GET
{ 'user-agent': 'curl/7.37.1',
host: '127.0.0.1:8081',
accept: '*/*' }
/
С этого момента я переключался туда-сюда между двумя консолями.
Второй запрос содержит путь к документу на сервере и параметр со значением:
$ curl http://127.0.0.1:8081/some/path?field=value
Вывод в консоль был таким же, как и в предыдущем примере, кроме последней строки, которая содержит url
.
GET
{ 'user-agent': 'curl/7.37.1',
host: '127.0.0.1:8081',
accept: '*/*' }
/some/path?field=value
Последней попыткой стала отправка POST-запроса с некоторыми данными с помощью curl:
$ curl --data "field=value" http://127.0.0.1:8081/
вывод выглядел вот так:
POST
{ 'user-agent': 'curl/7.37.1',
host: '127.0.0.1:8081',
accept: '*/*',
'content-length': '11',
'content-type': 'application/x-www-form-urlencoded' }
/
Первая строка показывает, что это действительно был POST
запрос, заголовок содержал дополнительные поля,
но сами данные не отображались.
Конечно, данные должны быть прочитаны и обработаны другим способом.
Прием HTTP POST запросов в Node.js
examples/node/http_client_request_post.js
var http = require('http');
var port = 8081;
var s = http.createServer();
s.on('request', function(request, response) {
response.writeHead(200);
console.log(request.method);
console.log(request.headers);
console.log(request.url);
var data = '';
request.on('data', function(chunk) {
data += chunk.toString();
});
request.on('end', function() {
console.log(data);
response.write('hi');
response.end();
});
});
s.listen(port);
console.log('Browse to http://127.0.0.1:' + port);
Это еще одна область, где видна неблокирующая природа Node.js.
Вместо простого чтения данных из объекта запроса, мы добавляем функцию обратного вызова (callback) к событию data
объекта request
.
Она [функция] будет вызываться каждый раз, когда придет новая партия данных.
Конечно, если данные это всего лишь 11 символов, как в нашем случае, тогда это не очень интересно,
но если вы отправляете большой объем данных, тогда нам важно их читать, не блокируя остальную часть сайта.
Теперь, когда у нас есть колбек, ожидающий данные, нам нужно отдать ответ тогда, когда все данные будут приняты.
Таким образом, мы добавили колбек для события end
объекта request
, и в нем мы выведем в консоль все данные,
отправленные клиентом, затем завершим ответ, вызвав метод end
объекта response
Давайте попробуем
$ node examples/node/http_client_request_post.js
Browse to http://127.0.0.1:8081
Обычный GET-запрос:
$ curl http://127.0.0.1:8081/
отработал как раньше:
GET
{ 'user-agent': 'curl/7.37.1',
host: '127.0.0.1:8081',
accept: '*/*' }
/
GET-запрос с указанием документа и параметрами:
$ curl http://127.0.0.1:8081/some/path?field=value
результат:
GET
{ 'user-agent': 'curl/7.37.1',
host: '127.0.0.1:8081',
accept: '*/*' }
/some/path?field=value
И как ведет себя POST
-запрос
$ curl --data "field=value" http://127.0.0.1:8081/
результат в консоли:
POST
{ 'user-agent': 'curl/7.37.1',
host: '127.0.0.1:8081',
accept: '*/*',
'content-length': '11',
'content-type': 'application/x-www-form-urlencoded' }
/
field=value
Таким образом, удалось получить данные, отправленные клиентом.