Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 8946

[Node.js] response.writeHeadとresponse.setHeaderって何が違うの?

$
0
0

はじめに

Node.jsを勉強していて、setHeaderとwriteHeadって何が違うの...?となったのでソースコードなどから調べてみました。

setHeaderのソースコードを見てみる

setHeaderの実装部分を示します。setHeaderはheadersに名前と値を格納しているだけということがわかります。
headersに値を格納しているので、例えばgetHeader(name)によって値を取得することができます。

OutgoingMessage.prototype.setHeader=functionsetHeader(name,value){if(this._header){thrownewERR_HTTP_HEADERS_SENT('set');}validateHeaderName(name);validateHeaderValue(name,value);letheaders=this[kOutHeaders];if(headers===null)this[kOutHeaders]=headers=ObjectCreate(null);headers[name.toLowerCase()]=[name,value];};

(https://github.com/nodejs/node/blob/master/lib/_http_outgoing.js)

writeHeadのソースコードを見てみる

writeHeadの一部を抜き出したものを示します。
this[kOutHeaders]がtruthyな値かどうかで場合分けがされています。this[kOutHeaders]はヘッダーの名前と値をキャッシュしているデータになるので、setHeader()などでキャッシュされているかどうかで分かれることになります。
setHeader()が呼び出されていた場合、writeHeadの内部でもsetHeader()が実行され、writeHeadの引数で指定した名前と値もキャッシュされます。
一方、setHeader()が呼び出されていない場合、引数で指定した名前と値をheadersに格納するだけとなります。

letheaders;if(this[kOutHeaders]){// Slow-case: when progressive API and header fields are passed.letk;if(ArrayIsArray(obj)){if(obj.length%2!==0){thrownewERR_INVALID_ARG_VALUE('headers',obj);}for(letn=0;n<obj.length;n+=2){k=obj[n+0];if(k)this.setHeader(k,obj[n+1]);}}elseif(obj){constkeys=ObjectKeys(obj);for(leti=0;i<keys.length;i++){k=keys[i];if(k)this.setHeader(k,obj[k]);}}if(k===undefined&&this._header){thrownewERR_HTTP_HEADERS_SENT('render');}// Only progressive api is usedheaders=this[kOutHeaders];}else{// Only writeHead() calledheaders=obj;}

(https://github.com/nodejs/node/blob/299984561eff45bddc5bb802e5b22d47277e5ca5/lib/_http_server.js)

具体例

setHeaderを使っている場合は、console.log(res.getHeader("content-Type"));が実行されると
content-Type':'text/html; charset=UTF-8と表示されます。

"use strict"consthttp=require("http");constserver=http.createServer((req,res)=>{res.setHeader('Set-Cookie',"accessed_date="+Date.now()+";");res.writeHead(200,{'content-Type':'text/html; charset=UTF-8'});res.end();console.log(res.getHeader("content-Type"));// => 'content-Type':'text/html; charset=UTF-8'});constport=8000;server.listen(port,()=>{console.info("listening on"+port);})

setHeaderを使っていない場合undefinedと表示されます。

"use strict"consthttp=require("http");constserver=http.createServer((req,res)=>{res.writeHead(200,{'content-Type':'text/html; charset=UTF-8'});res.end();console.log(res.getHeader("content-Type"));// => undefined});constport=8000;server.listen(port,()=>{console.info("listening on"+port);})

まとめ

  • setHeaderを使うと値をキャッシュすることができる
    •  例えばgetHeaderなどで値を取り出すことができる
    •  setHeaderの実行後はwriteHeadでも値のキャッシュが行われるようになる
  • writeHeadだけを使うと値のキャッシュなどが行われない
    • その分、処理は早くなる

Viewing all articles
Browse latest Browse all 8946