从零开始学习Node.js系列教程之设置HTTP头的方法示

//basic server的配置文件 var port = 3000; var server = require('./basicserver').createServer(); server.useFavIcon("localhost", "./docroot/favicon.png"); server.addContainer(".*", "/l/(.*)$", require('./redirector'), {}) server.docroot("localhost", "https://www.jb51.net/", "./docroot"); //server.useFavIcon("127.0.0.1", "./docroot/favicon.png"); //server.docroot("127.0.0.1", "https://www.jb51.net/", "./docroot"); server.listen(port);

basicserver.js

Response Header 服务器发送到客户端

文件扩展名不足以完全恰当的标识文件类型,而且文件扩展名没有标准,于是,人们设计了Content-Type头和整个MIME类型标准来作为数据类型的表示系统。

对于某些应用,特别是一些处理固定数据的小型应用,我们可以精准的知道该使用哪一种Content-Type头,因为应用发送的数据是特定已知的。然而staticHandler能发送任何文件,通常不知道该使用哪种Content-Type。通过匹配文件扩展名列表和Content-Type可以解决这个问题,但是这个方案不完美。最好的实践方案是使用一个外部的配置文件,它通常由操作系统提供。

MIME npm包使用了Apache项目的mime.types文件,该文件包含超过600个Content-Type的有关数据,如果有需要,mime模块也支持添加自定义的MIME类型。

npm install mime

var mime = require('mime'); var mimeType = mime.lookup('image.gif'); //==> image/gif res.setHeader('Content-Type', mimeType);

一些相关的HTTP头:

Content-Encoding 数据被编码时使用,例如gzip
Content-Language 内容中使用的语言
Content-Length 字节数
Content-Location 能取到数据的一个候补位置
Content-MD5 内容主题的MD5校验和

HTTP协议是无状态的,意味着web服务器不能辨认不同的请求发送端。现在普遍的做法是,服务器发送cookie到客户端浏览器,cookie中定义了登陆用户的身份,对于每一次请求,web浏览器都会发送对应所访问网站的cookie。

发送cookie时,我们应以如下方式为Set-Cookie或Set-Cookie2头设一个值:

res.setHeader('Set-Cookie2', ..cookie value..);

/* Basic Server的核心模块会创建一个HTTP服务器对象,附加Basic Server上用于检查请求,然后给予适当响应的功能 Basic Server可以通过判断Host头部匹配的容器对象响应来自多个域名的请求 */ var http = require('http'); var url = require('url'); exports.createServer = function(){ var htserver = http.createServer(function(req, res){ req.basicServer = {urlparsed: url.parse(req.url, true)}; processHeaders(req, res); dispatchToContainer(htserver, req, res); }); htserver.basicServer = {containers: []}; htserver.addContainer = function(host, path, module, options){ if (lookupContainer(htserver, host, path) != undefined){ throw new Error("Already mapped " + host + "https://www.jb51.net/" + path); } htserver.basicServer.containers.push({host: host, path: path, module: module, options: options}); return this; } htserver.useFavIcon = function(host, path){ return this.addContainer(host, "/favicon.ico", require('./faviconHandler'), {iconPath: path}); } htserver.docroot = function(host, path, rootPath){ return this.addContainer(host, path, require('./staticHandler'), {docroot: rootPath}); } return htserver; } var lookupContainer = function(htserver, host, path){ for (var i = 0; i < htserver.basicServer.containers.length; i++){ var container = htserver.basicServer.containers[i]; var hostMatches = host.toLowerCase().match(container.host); var pathMatches = path.match(container.path); if (hostMatches !== null && pathMatches !== null){ return {container: container, host: hostMatches, path: pathMatches}; } } return undefined; } //用于搜索req.headers数组以查找cookie和host头部,因为这两个字段对请求的分派都很重要 //这个函数在每一个HTTP请求到达时都会被调用 //还有很多其他的HTTP头部字段(Accept Accept-Encoding Accept-Language User-Agent) var processHeaders = function(req, res){ req.basicServer.cookies = []; var keys = Object.keys(req.headers); for (var i = 0; i < keys.length; i++){ var hname = keys[i]; var hval = req.headers[hname]; if (hname.toLowerCase() === "host"){ req.basicServer.host = hval; } //提取浏览器发送的cookie if (hname.toLowerCase() === "cookie"){ req.basicServer.cookies.push(hval); } } } //查找匹配的容器,分派请求到对应的容器中 //这个函数在每一个HTTP请求到达时都会被调用 var dispatchToContainer = function(htserver, req, res){ var container = lookupContainer(htserver, req.basicServer.host, req.basicServer.urlparsed.pathname); if (container !== undefined){ req.basicServer.hostMatches = container.host; req.basicServer.pathMatches = container.path; req.basicServer.container = container.container; container.container.module.handle(req, res); }else { res.writeHead(404, {'Content-Type': 'text/plain'}); res.end("no handler found for " + req.basicServer.host + "https://www.jb51.net/" + req.basicServer.urlparsed); } }

staticHandler.js

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wyppyf.html