基本功能

不急着写下第一行代码,而是先梳理一下就基本功能而言有哪些步骤。

  1. 在本地根据指定端口启动一个http server,等待着来自客户端的请求
  2. 当请求抵达时,根据请求的url,以设置的静态文件目录为base,映射得到文件位置
  3. 检查文件是否存在
  4. 如果文件不存在,返回404状态码,发送not found页面到客户端
  5. 如果文件存在:
    • 打开文件待读取
    • 设置response header
    • 发送文件到客户端
  6. 等待来自客户端的下一个请求

实现基本功能

代码结构

创建一个nodejs-static-webserver目录,在目录内运行npm init初始化一个package.json文件。

mkdir nodejs-static-webserver && cd "$_"
// initialize package.json
npm init

接着创建如下文件目录:

-- config
---- default.json
-- static-server.js
-- app.js

default.json

{
"port": 9527,
"root": "/Users/sheila1227/Public",
"indexPage": "index.html"
}

default.js存放一些默认配置,比如端口号、静态文件目录(root)、默认页(indexPage)等。当这样的一个请求http://localhost:9527/myfiles/抵达时. 如果根据root映射后得到的目录内有index.html,根据我们的默认配置,就会给客户端发回index.html的内容。

static-server.js

const http = require('http');
const path = require('path');
const config = require('./config/default'); class StaticServer {
constructor() {
this.port = config.port;
this.root = config.root;
this.indexPage = config.indexPage;
} start() {
http.createServer((req, res) => {
const pathName = path.join(this.root, path.normalize(req.url));
res.writeHead(200);
res.end(`Requeste path: ${pathName}`);
}).listen(this.port, err => {
if (err) {
console.error(err);
console.info('Failed to start server');
} else {
console.info(`Server started on port ${this.port}`);
}
});
}
} module.exports = StaticServer;

在这个模块文件内,我们声明了一个StaticServer类,并给其定义了start方法,在该方法体内,创建了一个server对象,监听rquest事件,并将服务器绑定到配置文件指定的端口。在这个阶段,我们对于任何请求都暂时不作区分地简单地返回请求的文件路径。path模块用来规范化连接和解析路径,这样我们就不用特意来处理操作系统间的差异。

app.js

const StaticServer = require('./static-server');

(new StaticServer()).start();

在这个文件内,调用上面的static-server模块,并创建一个StaticServer实例,调用其start方法,启动了一个静态资源服务器。这个文件后面将不需要做其他修改,所有对静态资源服务器的完善都发生在static-server.js内。

在目录下启动程序会看到成功启动的log:

> node app.js

Server started on port 9527

在浏览器中访问,可以看到服务器将请求路径直接返回了。

路由处理

之前我们对任何请求都只是向客户端返回文件位置而已,现在我们将其替换成返回真正的文件:

    routeHandler(pathName, req, res) {

    }

    start() {
http.createServer((req, res) => {
const pathName = path.join(this.root, path.normalize(req.url));
this.routeHandler(pathName, req, res);
}).listen(this.port, err => {
...
});
}

将由routeHandler来处理文件发送。

读取静态文件

读取文件之前,用fs.stat检测文件是否存在,如果文件不存在,回调函数会接收到错误,发送404响应。

   respondNotFound(req, res) {
res.writeHead(404, {
'Content-Type': 'text/html'
});
res.end(`<h1>Not Found</h1><p>The requested URL ${req.url} was not found on this server.</p>`);
} respondFile(pathName, req, res) {
const readStream = fs.createReadStream(pathName);
readStream.pipe(res);
} routeHandler(pathName, req, res) {
fs.stat(pathName, (err, stat) => {
if (!err) {
this.respondFile(pathName, req, res);
} else {
this.respondNotFound(req, res);
}
});
}

Note:

读取文件,这里用的是流的形式createReadStream而不是readFile,是因为后者会在得到完整文件内容之前将其先读到内存里。这样万一文件很大,再遇上多个请求同时访问,readFile就承受不来了。使用文件可读流,服务端不用等到数据完全加载到内存再发回给客户端,而是一边读一边发送分块响应。这时响应里会包含如下响应头:

Transfer-Encoding:chunked

默认情况下,可读流结束时,可写流的end()方法会被调用。

node 静态伺服(搭建服务)的更多相关文章

  1. node.js简单搭建服务,访问本地站点文件

    1.安装nodejs服务(从官网下载安装),node相当于apache服务器 2.在自己定义的目录下新建服务器文件如 server.js 例如,我在D:\nodeJs下创建了server.js文件 v ...

  2. 绝版Node--Sequlize搭建服务(Node全栈之路)

    绝版Node--Sequlize搭建服务(Node全栈之路) 参考资料:https://itbilu.com/nodejs/npm/VkYIaRPz-.html 准备环境:Mysql,Node 前沿: ...

  3. 使用node搭建服务时,服务可以启动,但是无法访问

    一开始搭建的是没有问题,能够正常启动和访问,然后吃了个饭回来就变成只能启动,浏览器访问不了了. 说真的,这是一个常识问题.使用node搭建服务访问本地文件,服务搭建的没有问题,能够正常启动.但是在浏览 ...

  4. 使用node+puppeteer+express搭建截图服务

    使用node+puppeteer+express搭建截图服务 转载请注明出处https://www.cnblogs.com/funnyzpc/p/14222807.html 写在之前 一开始我们的需求 ...

  5. 《JERRY Hexo & GitHub 静态网站搭建说明》

    JERRY-Hexo-GitHub <JERRY Hexo & GitHub 静态网站搭建说明> 原创内容,转载请注明出处! 一.前言 1.1 什么是 Hexo? 一个基于 Nod ...

  6. paip.最好的脚本语言node js 环境搭建连接mysql

    paip.最好的脚本语言node js 环境搭建连接mysql #====下载node...走十一个exe..容易的.. 1 #0----Hello world   .js 2 #---------模 ...

  7. CAS 5.1.x 的搭建和使用(二)—— 通过Overlay搭建服务端-其它配置说明

    CAS单点登录系列: CAS 5.1.x 的搭建和使用(一)—— 通过Overlay搭建服务端 CAS5.1.x 的搭建和使用(二)—— 通过Overlay搭建服务端-其它配置说明 CAS5.1.x ...

  8. Node.js环境搭建&&npm安装

    Node.js环境搭建 什么使Node.js呢?我们知道JavaScript开始作为客户端语言,但早已在浏览器端一统江湖,这时,野心越来越大,它就想向服务器端拓展了,于是Node.js就是这样的,我们 ...

  9. Node.js发布http服务

    Node.js发布http服务 2018-11-09 09:43:03   Visit  0 简单服务 var http = require(\'http\'); http.createServer( ...

随机推荐

  1. pip指定网址安装

    用pip安装库的有时候很慢都动不了 ,访问速度很慢,不稳定等缺陷 所以呢为了解决这个问题只能指定网址源下载的话速度就很快了 pip安装默认访问的是https://pypi.Python.org/sim ...

  2. [原创]K8 MSF Bind Shell TCP 连接工具

    工具: K8_MSFBindShellClient_20170524[K.8]编译: 自己查壳组织: K8搞基大队[K8team]作者: K8拉登哥哥博客: http://qqhack8.blog.1 ...

  3. vue教程2-07 微博评论功能

    vue教程2-07 微博评论功能 <!doctype html> <html> <head> <meta charset="utf-8"& ...

  4. web工程迁移---weblogic8迁移到jboss5遇到的异常

    原有的web工程是在weblogic8上运行的,但现在的要求是要运行到jboss5中,为如后迁移到更高版本的jboss做准备 由于我对weblogic没有过研究,所以之前的步骤都是有别人进行的,在进行 ...

  5. C++ 操作符、局部 全局变量及自动转换原则

    1.&:表示与操作,eg:2&1=2&&:表示and操作,eg:1&&0=0|:表示或操作,eg:2|1=3||:表示or操作,eg:1||0=12.全 ...

  6. React VR 技术开发群 579149907

    React VR 技术开发群 579149907,欢迎加入讨论!分享经验!

  7. spring mvc 数据转换

    项目目录结构 User.java package org.mythsky.springmvcdemo.model; import org.springframework.format.annotati ...

  8. php -- 显示当前时间

    默认为UTC ----- 002-time.php ----- <!DOCTYPE html> <html> <head> <meta http-equiv= ...

  9. C语言版 Hello World

    C语言的Hello World 程序, 需要引入 <stdio.h> 头文件,输出使用 printf()方法: #include <stdio.h> int main() { ...

  10. Java RMI 框架(远程方法调用)

    转自:http://haolloyin.blog.51cto.com/1177454/332426 RMI(即Remote Method Invoke 远程方法调用).在Java中,只要一个类exte ...