Node Express Content-Length

Я использую node.js и выражаюсь в небольшом проекте. Я установил заголовок ответа как удар:

res.set({'Content-Type':'text/plain;charset=utf-8',    
'Content-Length': Buffer.byteLength(data, 'utf-8')});       

Я могу использовать console.log длина данных для печати 317.

Но на консоли браузера я просто получаю следующее:

Соединение: keep-alive
Content-Encoding: gzip
Content-Type: text / plain; charset = utf-8
Дата: сб, 01 июня 2013 г. 08:21:59 GMT
Transfer- Кодировка: фрагментированная
Различная: Accept-Encoding
X-Powered-By: Express

Итак, почему исчезла content-length?


person Allen Heavey    schedule 01.06.2013    source источник


Ответы (1)


В ответе есть Transfer-Encoding: chunked. Здесь Content-Length не применимо, потому что содержимое отправляется одной или несколькими частями (фрагментами) внутри тела ответа с маркером, указывающим длину в байтах каждого отдельного фрагмента. http://en.wikipedia.org/wiki/Chunked_transfer_encoding

Node.js по умолчанию Transfer-Encoding: chunked. Однако это отключено установкой заголовка Content-Length в собственном объекте HTTP-ответа. В документации модуля HTTP говорится:

Отправка заголовка Content-length отключит кодировку фрагментов по умолчанию.

Судя по заголовку Content-Encoding:gzip в вашем ответе, вы, вероятно, включили промежуточное ПО connect.compress. По промежуточного слоя connect.compress удаляет заголовок Content-Length.

В любом случае, если вы сами не создаете сжатый с помощью gzip-содержимого контент, заголовок Content-Length, который вы сгенерируете самостоятельно, наверняка не подходит для окончательного (сжатого с помощью gzip) тела ответа. К счастью, промежуточное ПО Connect позаботится об этом за вас.

При использовании Express или Connect вы не должны предполагать, что вещи, которые вы «отправляете» с объектом res, действительно отправляются клиенту именно таким образом. Между ними есть промежуточное ПО. Все промежуточное ПО имеет возможность изменять что угодно в ответе, включая изменение тела ответа, а также добавление, удаление и изменение заголовков. То же самое и с запросом.

См. Также эти вопросы:

person Myrne Stol    schedule 01.06.2013
comment
Извините, я не знаю, кто проголосовал против, но вы правы. Большое Вам спасибо. После комментария app.use(express.compress()); отображается длина содержимого. Но могу ли я использовать и gzip, и длину содержимого? - person Allen Heavey; 01.06.2013
comment
@DMDGeeker, в принципе да, можно использовать Transfer-Encoding: gzip и Content-Length вместе. Однако не с промежуточным программным обеспечением express.compress. Он просто не поддерживает этого. В принципе, отправка заголовка Content-Length предпочтительнее, если вы знаете длину ответа. Вы можете сами сжимать контент или искать другое промежуточное программное обеспечение для сжатия. Но Content-Length должен отражать фактический отправленный контент. Он должен отражать байтовую длину конечного (возможно, сжатого) тела. - person Myrne Stol; 01.06.2013
comment
Причина, по которой connect.compress не добавляет новый Content-Length к ответу, заключается в том, что для этого потребуется буферизация сжатого тела ответа. В конце концов, длина содержимого может быть известна только тогда, когда буфер заполнен. - person Myrne Stol; 01.06.2013
comment
Если вы сжимаете буфер самостоятельно, используя zlib.gzip, а затем выполняете res.set ({"Transfer-Encoding": "gzip"}), connect.compress промежуточное ПО не коснется его. - person Myrne Stol; 01.06.2013
comment
Спасибо. Я попробую. - person Allen Heavey; 01.06.2013