使用node.js手撸一个建静态web服务器,内部cv指南(代码片段)

@魏大大 @魏大大     2022-10-22     725

关键词:

  1. 文章里有全部代码,也可以积分下载
  2. 操作步骤如上图
  3. 文章结束

话说这个键盘真漂亮~~


文章目录


使用Node.js手撸一个建静态Web服务器

一、动静态服务器的概念

1.1 静态Web服务器概念

我们通常称静态Web服务器静态网站,其主要特征就是服务器上的所有内容都是现成的,不需要后端做额外的处理。当我们向静态服务器发送网页请求时,服务器只需要根据我们的请求路径(URL),返回对应的html文件就行了。

静态网站是指全部由HTML标准通用标记语言的子集)代码格式页面组成的网站,所有的内容包含在网页文件中。网页上也可以出现各种视觉动态效果,如GIF动画、FLASH动画、滚动字幕等,而网站主要是静态化的页面代码组成,一般文件名均以htmhtmlshtml等为后缀。—— 百度百科

与静态网站对应的是我们最常见的动态Web服务器,此类服务器最大的特征就是所有资源通常不是以html形式存储的,而是需要后端查询数据,组成网页之后再返回给用户,每个用户看到的内容可能是都不相同的。例如,在Java搭建的Web服务器中,我们可以使用JSP拼接网页,形成特定于用户的页面。

(1)动态网页以数据库技术为基础,可以大大降低网站维护的工作量;

(2)采用动态网页技术的网站可以实现更多的功能,如用户注册、用户登录、在线调查、用户管理、订单管理等等;

(3)动态网页实际上并不是独立存在于服务器上的网页文件,只有当用户请求时服务器才返回一个完整的网页;

(4)动态网页中的“?”搜索引擎一般不可能从一个网站的数据库中访问全部网页,或者出于技术方面的考虑,搜索蜘蛛不去抓取网址中“?”后面的内容,因此采用动态网页的网站在进行搜索引擎推广时需要做一定的技术处理才能适应搜索引擎的要求。

(5)静态网站因为没有和数据库连接,所以要有动态网站的效果就必须制作大量的网页,其中许多网页只能是虚假网页,根本实现不了动态网站的功能。

—— 百度百科

1.2 静态Web服务器的优点

由于静态服务器不需要后端数据库,所以结构非常简单,非常适合例如文档管理、博客等场景。就以写博客本身而言,我认为静态网站有以下特点:

  1. 需要的服务器配置低,最基础的服务器就可以满足大部分人的性能需求;

  2. 响应速度快,内容都是现成的html,直接访问即可获得结果;

  3. 一个html对应一个url,内容稳定,容易被搜索引擎检索;

  4. 制作简单,只需要在服务器搭建完成后,将文件防止指定位置即可;

以上有点都是针对静态博客系统而言的,如果使用纯静态服务器制作一个大型的其他类型网站可能代价比较大。

1.3 快速搭建的途径

如果个人希望快速搭建一个静态服务器,可以使用基于Node.jshttp-server包,可以在一分钟内完成服务器的搭建,步骤如下:

  1. 下载http-server包,记得全局安装
npm i http-server -g
  1. 进入服务器文件夹,启动服务器
http-server -a 127.0.0.1 -p 9999

这样服务器就启动了,根目录就是启动服务器命令执行的目录。

访问localhost:9999就可以看到所有的文件了,下面是我的文件内容:

如果我们点击文件名,就会得到对应的文件,例如我们点击*.html,就可以得到网页:

这看起来就像是个FTP服务器,难道我们就止步于此了吗?

非也,一个合格的程序员都是要手撸才会快乐!!

二、 手撸指南

2.1 框架搭建

我们使用基础的Node.js内置模块即可完成搭建,所以不需要安装额外的工具包。

主要的工作是创建一个服务器目录,结构如下:

web_server/					//根目录
	|- static/
	|	|- css/
	|	|	|- style.css	//样式
	|	|- js/
	|	|	|- common.js	//js
	|	|- index.js			//主页
	|- app.js         		//服务器文件
    |- mime.json			//扩展名配置

2.2 Ctrl+C/V

  1. app.js
const http = require('http');
const fs = require('fs')
const url = require('url')
const path = require('path')

FileMimes = JSON.parse(fs.readFileSync('./mime.json').toString())

http.createServer(function (req, res) 
    //1.获取地址
    let pathname = url.parse(req.url).pathname
    pathname = pathname == '/' ? '/index.html' : pathname
    let extname = path.extname(pathname)
    //2.fs读取文件
    if (pathname != '/favicon.ico') 
        fs.readFile('./static' + pathname, async (err, data) => 
            if (err) 
                res.writeHead(404,  'Content-Type': 'text/html;charset="utf-8"' )
                res.end(err.message)
                return
            
            if (!err) 
                // 3. 针对不同的文件返回不同的内容头
                let mime = FileMimes[extname]
                res.writeHead(200,  'Content-Type': mime + ';charset="utf-8"' )
                res.end(data)
            
        )
    

).listen(8081);

console.log('Server running at http://127.0.0.1:8081/');
  1. mime.json
 ".323":"text/h323" ,
  ".3gp":"video/3gpp" ,
  ".aab":"application/x-authoware-bin" ,
  ".aam":"application/x-authoware-map" ,
  ".aas":"application/x-authoware-seg" ,
  ".acx":"application/internet-property-stream" ,
  ".ai":"application/postscript" ,
  ".aif":"audio/x-aiff" ,
  ".aifc":"audio/x-aiff" ,
  ".aiff":"audio/x-aiff" ,
  ".als":"audio/X-Alpha5" ,
  ".amc":"application/x-mpeg" ,
	...//实在太长,就不贴这里了,文末有完整代码

2.3 启动服务器

node ./app.js

启动效果如下:

PS E:\\Code\\Node\\demos\\03-static_web_server> node .\\app.js   
Server running at http://127.0.0.1:8081/

访问localhost:8081即可得到index.html页面。

2.4 部署服务器(简单过程)

也可以部署到远端的服务器
1. 买服务器

当前流行的服务器提供商包括
- 腾讯云
- 阿里云
- 华为云

不过现在CSDN也来凑热闹了:CSDN云,CSDN好像是基于腾讯云的,价格上都差不多。

2. 买域名(非必须,可以使用IP直接访问)
3. 网站备案
4. 部署
静态网站的部署也非常简单,由于很少出错,而且需要经常启停上传新的博客文件,所以直接复制文件到服务器,然后使用

node ./app.js

就可以了。

代码下载


三、总结

基于Node.js的静态服务器搭建非常简单,我们可以使用http-server包,也可以基于Node手写代码。

手写代码最核心的内容是mime.json文件,也就是对于不同的文件类型,赋予response不同的返回头。

文章结束


下面是mime.json代码(老长了):

 
  ".323":"text/h323" ,
  ".3gp":"video/3gpp" ,
  ".aab":"application/x-authoware-bin" ,
  ".aam":"application/x-authoware-map" ,
  ".aas":"application/x-authoware-seg" ,
  ".acx":"application/internet-property-stream" ,
  ".ai":"application/postscript" ,
  ".aif":"audio/x-aiff" ,
  ".aifc":"audio/x-aiff" ,
  ".aiff":"audio/x-aiff" ,
  ".als":"audio/X-Alpha5" ,
  ".amc":"application/x-mpeg" ,
  ".ani":"application/octet-stream" ,
  ".apk":"application/vnd.android.package-archive" ,
  ".asc":"text/plain" ,
  ".asd":"application/astound" ,
  ".asf":"video/x-ms-asf" ,
  ".asn":"application/astound" ,
  ".asp":"application/x-asap" ,
  ".asr":"video/x-ms-asf" ,
  ".asx":"video/x-ms-asf" ,
  ".au":"audio/basic" ,
  ".avb":"application/octet-stream" ,
  ".avi":"video/x-msvideo" ,
  ".awb":"audio/amr-wb" ,
  ".axs":"application/olescript" ,
  ".bas":"text/plain" ,
  ".bcpio":"application/x-bcpio" ,
  ".bin ":"application/octet-stream" ,
  ".bld":"application/bld" ,
  ".bld2":"application/bld2" ,
  ".bmp":"image/bmp" ,
  ".bpk":"application/octet-stream" ,
  ".bz2":"application/x-bzip2" ,
  ".c":"text/plain" ,
  ".cal":"image/x-cals" ,
  ".cat":"application/vnd.ms-pkiseccat" ,
  ".ccn":"application/x-cnc" ,
  ".cco":"application/x-cocoa" ,
  ".cdf":"application/x-cdf" ,
  ".cer":"application/x-x509-ca-cert" ,
  ".cgi":"magnus-internal/cgi" ,
  ".chat":"application/x-chat" ,
  ".class":"application/octet-stream" ,
  ".clp":"application/x-msclip" ,
  ".cmx":"image/x-cmx" ,
  ".co":"application/x-cult3d-object" ,
  ".cod":"image/cis-cod" ,
  ".conf":"text/plain" ,
  ".cpio":"application/x-cpio" ,
  ".cpp":"text/plain" ,
  ".cpt":"application/mac-compactpro" ,
  ".crd":"application/x-mscardfile" ,
  ".crl":"application/pkix-crl" ,
  ".crt":"application/x-x509-ca-cert" ,
  ".csh":"application/x-csh" ,
  ".csm":"chemical/x-csml" ,
  ".csml":"chemical/x-csml" ,
  ".css":"text/css" ,
  ".cur":"application/octet-stream" ,
  ".dcm":"x-lml/x-evm" ,
  ".dcr":"application/x-director" ,
  ".dcx":"image/x-dcx" ,
  ".der":"application/x-x509-ca-cert" ,
  ".dhtml":"text/html" ,
  ".dir":"application/x-director" ,
  ".dll":"application/x-msdownload" ,
  ".dmg":"application/octet-stream" ,
  ".dms":"application/octet-stream" ,
  ".doc":"application/msword" ,
  ".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document" ,
  ".dot":"application/msword" ,
  ".dvi":"application/x-dvi" ,
  ".dwf":"drawing/x-dwf" ,
  ".dwg":"application/x-autocad" ,
  ".dxf":"application/x-autocad" ,
  ".dxr":"application/x-director" ,
  ".ebk":"application/x-expandedbook" ,
  ".emb":"chemical/x-embl-dl-nucleotide" ,
  ".embl":"chemical/x-embl-dl-nucleotide" ,
  ".eps":"application/postscript" ,
  ".epub":"application/epub+zip" ,
  ".eri":"image/x-eri" ,
  ".es":"audio/echospeech" ,
  ".esl":"audio/echospeech" ,
  ".etc":"application/x-earthtime" ,
  ".etx":"text/x-setext" ,
  ".evm":"x-lml/x-evm" ,
  ".evy":"application/envoy" ,
  ".exe":"application/octet-stream" ,
  ".fh4":"image/x-freehand" ,
  ".fh5":"image/x-freehand" ,
  ".fhc":"image/x-freehand" ,
  ".fif":"application/fractals" ,
  ".flr":"x-world/x-vrml" ,
  ".flv":"flv-application/octet-stream" ,
  ".fm":"application/x-maker" ,
  ".fpx":"image/x-fpx" ,
  ".fvi":"video/isivideo" ,
  ".gau":"chemical/x-gaussian-input" ,
  ".gca":"application/x-gca-compressed" ,
  ".gdb":"x-lml/x-gdb" ,
  ".gif":"image/gif" ,
  ".gps":"application/x-gps" ,
  ".gtar":"application/x-gtar" ,
  ".gz":"application/x-gzip" ,
  ".h":"text/plain" ,
  ".hdf":"application/x-hdf" ,
  ".hdm":"text/x-hdml" ,
  ".hdml":"text/x-hdml" ,
  ".hlp":"application/winhlp" ,
  ".hqx":"application/mac-binhex40" ,
  ".hta":"application/hta" ,
  ".htc":"text/x-component" ,
  ".htm":"text/html" ,
  ".html":"text/html" ,
  ".hts":"text/html" ,
  ".htt":"text/webviewhtml" ,
  ".ice":"x-conference/x-cooltalk" ,
  ".ico":"image/x-icon" ,
  ".ief":"image/ief" ,
  ".ifm":"image/gif" ,
  ".ifs":"image/ifs" ,
  ".iii":"application/x-iphone" ,
  ".imy":"audio/melody" ,
  ".ins":"application/x-internet-signup" ,
  ".ips":"application/x-ipscript" ,
  ".ipx":"application/x-ipix" ,
  ".isp":"application/x-internet-signup" ,
  ".it":"audio/x-mod" ,
  ".itz":"audio/x-mod" ,
  ".ivr":"i-world/i-vrml" ,
  ".j2k":"image/j2k" ,
  ".jad":"text/vnd.sun.j2me.app-descriptor" ,
  ".jam":"application/x-jam" ,
  ".jar":"application/java-archive" ,
  ".java":"text/plain" ,
  ".jfif":"image/pipeg" ,
  ".jnlp":"application/x-java-jnlp-file" ,
  ".jpe":"image/jpeg" ,
  ".jpeg":"image/jpeg" ,
  ".jpg":"image/jpeg" ,
  ".jpz":"image/jpeg" ,
  ".js":"application/x-javascript" ,
  ".jwc":"application/jwc" ,
  ".kjx":"application/x-kjx" ,
  ".lak":"x-lml/x-lak" ,
  ".latex":"application/x-latex" ,
  ".lcc":"application/fastman" ,
  ".lcl":"application/x-digitalloca" ,
  ".lcr":"application/x-digitalloca" ,
  ".lgh":"application/lgh" ,
  ".lha":"application/octet-stream" ,
  ".lml":"x-lml/x-lml" ,
  ".lmlpack":"x-lml/x-lmlpack" ,
  ".log":"text/plain" ,
  ".lsf":"video/x-la-asf" ,
  ".lsx":"video/x-la-asf" ,
  ".lzh":"application/octet-stream" ,
  ".m13":"application/x-msmediaview" ,
  ".m14":"application/x-msmediaview" ,
  ".m15":"audio/x-mod" ,
  ".m3u":"audio/x-mpegurl" ,
  ".m3url":"audio/x-mpegurl" ,
  ".m4a":"audio/mp4a-latm" ,
  ".m4b":"audio/mp4a-latm" ,
  ".m4p":"audio/mp4a-latm" ,
  ".m4u":"video/vnd.mpegurl" ,
  ".m4v":"video/x-m4v" ,
  ".ma1":"audio/ma1" ,
  ".ma2":"audio/ma2" ,
  ".ma3":"audio/ma3" ,
  ".ma5":"audio/ma5" ,
  ".man":"application/x-troff-man" ,
  ".map":"magnus-internal/imagemap" ,
  ".mbd":"application/mbedlet" ,
  ".mct":"application/x-mascot" ,
  ".mdb":"application/x-msaccess" ,
  ".mdz":"audio/x-mod" ,
  ".me":"application/x-troff-me" ,
  ".mel":"text/x-vmel" ,
  ".mht":"message/rfc822" ,
  ".mhtml":"message/rfc822" ,
  ".mi":"application/x-mif" ,
  ".mid":"audio/mid" ,
  ".midi":"audio/midi" ,
  ".mif":"application/x-mif" ,
  ".mil":"image/x-cals" ,
  ".mio":"audio/x-mio" ,
  ".mmf":"application/x-skt-lbs" ,
  ".mng":"video/x-mng" ,
  ".mny":"application/x-msmoney" ,
  ".moc":"application/x-mocha" ,
  ".mocha":"application/x-mocha" ,
  ".mod":"audio/x-mod" ,
  ".mof":"application/x-yumekara" ,
  ".mol":"chemical/x-mdl-molfile" ,
  ".mop":"chemical/x-mopac-input" ,
  ".mov":"video/quicktime" ,
  ".movie":"video/x-sgi-movie" ,
  ".mp2":"video/mpeg" ,
  ".mp3":"audio/mpeg" ,
  ".mp4":"video/mp4" ,
  ".mpa":"video/mpeg" ,
  ".mpc":"application/vnd.mpohun.certificate" ,
  ".mpe":"video/mpeg" ,
  ".mpeg":"video/mpeg" ,
  ".mpg":"video/mpeg" ,
  ".mpg4":"video/mp4" ,
  ".mpga":"audio/mpeg" ,
  ".mpn":"application/vnd.mophun.application" ,
  ".mpp":"application/vnd.ms-project" ,
  ".mps":"application/x-mapserver" ,
  ".mpv2":使用node.js文档里的方法写一个web服务器

     刚刚看了node.js文档里的一个小例子,就是用node.js写一个web服务器的小例子 上代码(*^▽^*) //helloworld.js//使用node.js写一个服务器consthttp=require(‘http‘);consthostname=‘127.0.0.1‘constport=3000;consts 查看详情

手写koa.js源码

用Node.js写一个web服务器,我前面已经写过两篇文章了:第一篇是不使用任何框架也能搭建一个web服务器,主要是熟悉Node.js原生API的使用:使用Node.js原生API写一个web服务器第二篇文章是看了Express的基本用法,更主要的是看了下... 查看详情

node.js概述

...此,能够解决高并发访问的效率问题。【析】在Java/PHP等服务器端语言中,为每个客户端请求创建一个线程,每个线程耗费月2M,8G内存最大并发4000个,而Node.js可同时处理多达几万个客户端的连接。因此,当需要使用Web应用程序... 查看详情

使用静态内部类[重复]

】使用静态内部类[重复]【英文标题】:Usingastaticinnerclass[duplicate]【发布时间】:2015-02-1612:42:21【问题描述】:我有一个关于在以下代码中使用静态内部类的问题,改编自Eckel的ThinkinginJava第4版(第625页)。代码使用名为Node.js的... 查看详情

Node.js:如何使用 SOAP XML Web 服务

】Node.js:如何使用SOAPXMLWeb服务【英文标题】:Node.js:howtoconsumeSOAPXMLwebservice【发布时间】:2012-01-2903:03:13【问题描述】:我想知道使用node.js使用SOAPXMLWeb服务的最佳方式是什么谢谢!【问题讨论】:如果您使用node-soap并弄清楚如... 查看详情

node中的http模块(代码片段)

web服务器什么是Web服务器?当应用程序(客户端)需要某一个资源时,可以向一个台服务器,通过Http请求获取到这个资源;提供资源的这个服务器,就是一个Web服务器;目前有很多开源的Web服务器:Nginx、Apache(静态)、ApacheTom... 查看详情

利用node.js搭建简单web服务器的方法教程

前言使用Nodejs搭建Web服务器是学习Node.js比较全面的入门教程,因为要完成一个简单的Web服务器,你需要学习Nodejs中几个比较重要的模块,比如:http协议模块、文件系统、url解析模块、路径解析模块、以及301重定向问题,下面我... 查看详情

使用 Node.js 作为简单的 Web 服务器

】使用Node.js作为简单的Web服务器【英文标题】:UsingNode.jsasasimplewebserver【发布时间】:2011-08-3008:57:24【问题描述】:我想运行一个非常简单的HTTP服务器。对example.com的每个GET请求都应该得到index.html的服务,但作为常规的HTML页面... 查看详情

使用 Node.js 作为简单的 Web 服务器

】使用Node.js作为简单的Web服务器【英文标题】:UsingNode.jsasasimplewebserver【发布时间】:2011-08-3008:57:24【问题描述】:我想运行一个非常简单的HTTP服务器。对example.com的每个GET请求都应该得到index.html的服务,但作为常规的HTML页面... 查看详情

用node.js搭建一个静态资源站html,js,css正确加载跳转也完美实现!(代码片段)

昨天刚买了一个服务器想着用来测试一些自己的项目,由于是第一次建站,在tomcat,linux,node.js间想了好久最终因为node搭建比较方便没那么麻烦就决定用node.js来搭建网站项目。搭建服务器也很简单首先下载完安装node.js后,建立一... 查看详情

将子域发送到 node.js

...2011-08-0203:36:00【问题描述】:我的工作在运行apache的ubuntu服务器(10.10)上运行了几个不同的内部Web应用程序。我目前正在开发另一个Web应用程序,并且正在认真考虑在定制的node.jsWeb服务器之上进行开发。我想要这样做的原因是:... 查看详情

如何使用 mongodb (node.js) 在集合中创建一个包含所有值的数组

】如何使用mongodb(node.js)在集合中创建一个包含所有值的数组【英文标题】:Howtomakeanarrayofallthevaluesinsideacollectionwithmongodb(node.js)【发布时间】:2019-03-1114:57:00【问题描述】:我不断收到未决的承诺。varMongoClient=require(\'mongodb\').Mong... 查看详情

linux使用node.js建立访问静态网页的服务实例详解

Linux使用Node.js建立访问静态网页的服务实例详解一、安装node.js运行所需要的环境。二、创建node目录(/node/www),并在目录下创建node.js服务文件server.jsvarhttp=require(‘http‘); varfs=require(‘fs‘);//引入文件读取模块 vardocumentR... 查看详情

Node js HTTP 服务器/静态 Servlet POST 请求

】NodejsHTTP服务器/静态ServletPOST请求【英文标题】:NodejsHTTPServer/StaticServletPOSTrequest【发布时间】:2014-06-2917:41:59【问题描述】:我对Nodejs比较陌生。我已经基于angular-requirejs-seed构建了Nodejs/AngularApplication但是,当我使用express开发... 查看详情

在 node.js 中分离游戏服务器和 Web 服务器

】在node.js中分离游戏服务器和Web服务器【英文标题】:SeparatingGameServerandWebServerinnode.js【发布时间】:2012-12-0311:41:35【问题描述】:我几乎用node.js和socket.io完成了一个回合制多人游戏。我有express.js作为网络服务器,另一个类作... 查看详情

学习node.js搭建web服务器

开始学习使用node.js首先完成搭建一个web服务器。myweb.js1varhttp=require(‘http‘);2varurl=require(‘url‘);3varhostname=‘127.0.0.1‘;4varport=3000;5varbodystr="";6varserver=http.createServer(function(req,res){7res.statusCode 查看详情

在node.js中创建一个包含表单数据的文件[关闭]

...losed]【发布时间】:2016-07-1617:26:20【问题描述】:我想在服务器中创建一个包含表单数据的文件,当用户提交表单时,所有数据都保存在文件中【问题讨论】:你需要一种服务器端语言来接受和处理"server"和"AngularJS"这两个东西... 查看详情

创建一个简单的 node.js 静态服务器

】创建一个简单的node.js静态服务器【英文标题】:Creatingasimplenode.jsstaticserver【发布时间】:2017-12-0601:44:19【问题描述】:varexpress=require(\'express\');varapp=express();app.use(\'/\',express.static(\'./\'));app.listen(80);我通过“nodeserver.js”在cli中... 查看详情