您好,登錄后才能下訂單哦!
Node.js中怎么設(shè)置HTTP頭,相信很多沒有經(jīng)驗的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。
server.js
//basic server的配置文件 var port = 3000; var server = require('./basicserver').createServer(); server.useFavIcon("localhost", "./docroot/favicon.png"); server.addContainer(".*", "/l/(.*)$", require('./redirector'), {}) server.docroot("localhost", "/", "./docroot"); //server.useFavIcon("127.0.0.1", "./docroot/favicon.png"); //server.docroot("127.0.0.1", "/", "./docroot"); server.listen(port);
basicserver.js
Response Header 服務(wù)器發(fā)送到客戶端
文件擴展名不足以完全恰當(dāng)?shù)臉?biāo)識文件類型,而且文件擴展名沒有標(biāo)準(zhǔn),于是,人們設(shè)計了Content-Type頭和整個MIME類型標(biāo)準(zhǔn)來作為數(shù)據(jù)類型的表示系統(tǒng)。
對于某些應(yīng)用,特別是一些處理固定數(shù)據(jù)的小型應(yīng)用,我們可以精準(zhǔn)的知道該使用哪一種Content-Type頭,因為應(yīng)用發(fā)送的數(shù)據(jù)是特定已知的。然而staticHandler能發(fā)送任何文件,通常不知道該使用哪種Content-Type。通過匹配文件擴展名列表和Content-Type可以解決這個問題,但是這個方案不完美。最好的實踐方案是使用一個外部的配置文件,它通常由操作系統(tǒng)提供。
MIME npm包使用了Apache項目的mime.types文件,該文件包含超過600個Content-Type的有關(guān)數(shù)據(jù),如果有需要,mime模塊也支持添加自定義的MIME類型。
npm install mime
var mime = require('mime'); var mimeType = mime.lookup('image.gif'); //==> image/gif res.setHeader('Content-Type', mimeType);
一些相關(guān)的HTTP頭:
Content-Encoding
數(shù)據(jù)被編碼時使用,例如gzipContent-Language
內(nèi)容中使用的語言Content-Length
字節(jié)數(shù)Content-Location
能取到數(shù)據(jù)的一個候補位置Content-MD5
內(nèi)容主題的MD5校驗和
HTTP協(xié)議是無狀態(tài)的,意味著web服務(wù)器不能辨認(rèn)不同的請求發(fā)送端?,F(xiàn)在普遍的做法是,服務(wù)器發(fā)送cookie到客戶端瀏覽器,cookie中定義了登陸用戶的身份,對于每一次請求,web瀏覽器都會發(fā)送對應(yīng)所訪問網(wǎng)站的cookie。
發(fā)送cookie時,我們應(yīng)以如下方式為Set-Cookie或Set-Cookie2頭設(shè)一個值:
res.setHeader('Set-Cookie2', ..cookie value..);
/* Basic Server的核心模塊會創(chuàng)建一個HTTP服務(wù)器對象,附加Basic Server上用于檢查請求,然后給予適當(dāng)響應(yīng)的功能 Basic Server可以通過判斷Host頭部匹配的容器對象響應(yīng)來自多個域名的請求 */ 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 + "/" + 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數(shù)組以查找cookie和host頭部,因為這兩個字段對請求的分派都很重要 //這個函數(shù)在每一個HTTP請求到達(dá)時都會被調(diào)用 //還有很多其他的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; } //提取瀏覽器發(fā)送的cookie if (hname.toLowerCase() === "cookie"){ req.basicServer.cookies.push(hval); } } } //查找匹配的容器,分派請求到對應(yīng)的容器中 //這個函數(shù)在每一個HTTP請求到達(dá)時都會被調(diào)用 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 + "/" + req.basicServer.urlparsed); } }
staticHandler.js
//用于處理文件系統(tǒng)內(nèi)的文件,docroot選項指被存放文件所在文件夾的路徑,讀取該目錄下的指定文件 var fs = require('fs'); var mime = require('mime'); var sys = require('sys'); exports.handle = function(req, res){ if (req.method !== "GET"){ res.writeHead(404, {'Content-Type': 'text/plain'}); res.end("invalid method " + req.method); } else { var fname = req.basicServer.container.options.docroot + req.basicServer.urlparsed.pathname; if (fname.match(/\/$/)) fname += "index.html"; //如果URL以/結(jié)尾 fs.stat(fname, function(err, stats){ if (err){ res.writeHead(500, {'Content-Type': 'text/plain'}); res.end("file " + fname + " not found " + err); } else { fs.readFile(fname, function(err, buf){ if (err){ res.writeHead(500, {'Content-Type': 'text/plain'}); res.end("file " + fname + " not readable " + err); } else { res.writeHead(200, {'Content-Type': mime.lookup(fname), 'Content-Length': buf.length}); res.end(buf); } }); } }); } }
faviconHandler.js
//這個處理函數(shù)處理對favicon.ico的請求 //MIME模塊根據(jù)給出的圖標(biāo)文件確定正確的MIME類型,網(wǎng)站圖標(biāo)favicon可以是任何類型的圖片,但是我們必須要告訴瀏覽器是哪個類型 //MIME模塊,用于生成正確的Content-Type頭 var fs = require('fs'); var mime = require('mime'); exports.handle = function(req, res){ if (req.method !== "GET"){ res.writeHead(404, {'Content-Type': 'text/plain'}); res.end("invalid method " + req.method); } else if (req.basicServer.container.options.iconPath !== undefined){ fs.readFile(req.basicServer.container.options.iconPath, function(err, buf){ if (err){ res.writeHead(500, {'Content-Type': 'text/plain'}); res.end(req.basicServer.container.options.iconPath + "not found"); } else { res.writeHead(200, {'Content-Type': mime.lookup(req.basicServer.container.options.iconPath), 'Content-Length': buf.length}); res.end(buf); } }); } else { res.writeHead(404, {'Content-Type': 'text/plain'}); res.end("no favicon"); } }
redirector.js
/* 把一個域的請求重定向到另一個上,例如將www.example.com重定向到example.com上,或者使用簡短的URL跳轉(zhuǎn)到較長的URL 實現(xiàn)這兩種情況,我們需要在HTTP響應(yīng)中發(fā)送301(永久移除)或者302(臨時移除)狀態(tài)碼,并且指定location頭信息。有了這個組合 信號,web瀏覽器就知道要跳轉(zhuǎn)到另一個web位置了 */ //地址http://localhost:3000/l/ex1 會跳轉(zhuǎn)到http://example1.com var util = require('util'); var code2url = {'ex1': 'http://example1.com', 'ex2': "http://example2.com"}; var notFound = function(req, res){ res.writeHead(404, {'Content-Type': 'text/plain'}); res.end("no matching redirect code found for " + req.basicServer.host + "/" + req.basicServer.urlparsed.pathname); } exports.handle = function(req, res){ if (req.basicServer.pathMatches[1]){ var code = req.basicServer.pathMatches[1]; if (code2url[code]){ var url = code2url[code]; res.writeHead(302, {'Location': url}); res.end(); } else { notFound(req, res); } } else { notFound(req, res); } }
docroot目錄下:有favicon.png
index.html
<html> <head> </head> <body> <h2>Index</h2> <p>this is a index html.</p> </body> </html>
看完上述內(nèi)容,你們掌握Node.js中怎么設(shè)置HTTP頭的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。