其他章节请看:

前端学习 node 快速入门 系列

简易版 Apache

我们用 node 来实现一个简易版的 Apache:提供静态资源访问的能力

实现

直接上代码。

- demo
- static // 静态资源文件夹
- index.html // 主页
- 1.jpg
- 1.css
- 1.js
- index.js // 入口文件

index.html:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="1.css">
</head>
<body>
<p>欢迎来到首页</p>
<img src="1.jpg" alt="">
<section></section>
<script src='1.js'></script>
</body>
</html>

1.js 和 1.css:

document.querySelector('section').innerHTML = '我来自js' // js

body{color:red} // css

index.js(入口文件):

const http = require('http')
const fs = require('fs')
const server = http.createServer() const requestListener = (req, res) => {
const url = req.url
// 如果url是 '/',则返回主页
if(url === '/'){
fs.readFile('./static/index.html', (err, data) => {
if (err) throw err;
res.end(data)
});
return
} // 如果url不是 '/',则返回资源(找不到资源则报 404)
fs.readFile('./static/' + url, (err, data) => {
if (err) {
res.writeHead(404, {'Content-type':'text/html;charset=utf8'})
res.end('没有找到对应的资源')
}
res.end(data)
})
} server.on('request', requestListener)
server.listen('3000', () => {
console.log('服务器已启动')
})

启动服务器:

$ node index

检验服务器是否能提供静态资源访问的能力。

1. 浏览器输入 http://localhost:3000/1.css

页面显示:body{color:red}

2. 浏览器输入 http://localhost:3000/1.js

页面显示:document.querySelector('section').innerHTML = '鎴戞潵鑷猨s'(未指定编码,所以中文乱码。不碍事)

3. 浏览器输入 http://localhost:3000/1.jpg
页面显示:1.jpg(正常显示图片)

3 种静态资源都能正常响应。

访问主页:

浏览器输入:http://localhost:3000/index.html 或 http://localhost:3000/

页面显示:
欢迎来到首页
图片
我来自js

主页和其中的图片、css 以及 js 配合的非常完美。

:中文乱码的问题没有出现。因为我们在 html 页面中 使用了 <meta charset="utf-8"> 来指定编码。

通常访问不存在的资源会返回 404。请看:

浏览器输入:http://localhost:3000/2.css

页面显示:
没有找到对应的资源

扩展

至此,我们的简易版 apache 其实已经大功告成。在此基础之上,我们再扩展一下。

我的服务器我做主

理解这一点很重要:这个服务器完全由我们做主

现在所有的请求都会进入 requestListener() 方法,如果 url 是 '/',服务器就返回主页(index.html),否则就去 static 文件夹中读取相应的资源,如果没有找到对应的资源,就做 404 的处理。假如 requestListener() 是一个空方法,则说明我们的服务器不提供任何服务。

所有的请求都是 url

不要把 http://localhost:3000/1.css 中的 1.css 当成文件路径,而要当成 url,因为所有的请求都是 url。请看示例:

const requestListener = (req, res) => {
...
if(url.endsWith('.myCss')){
url = url.replace('.myCss', '.css') // url 得声明成 let
}
fs.readFile('./static/' + url, (err, data) => { // {1}
...
})
}

在 index.js 的 fs.readFile('./static/'(行{1}) 上面增加三行代码。

浏览器输入 http://localhost:3000/1.myCss

页面显示:body{color:red}

现在给服务器发送请求 http://localhost:3000/1.myCss,服务器也会返回 1.css 文件的内容。有些网站的 url 设计的非常优雅。请看:

http://product.dangdang.com/29200520.html

// 更优雅
https://www.douban.com/group/topic/214827461/

重定向

未登录的状态去访问页面,通常会被重定向到首页。我们来模拟一下:

if(url.endsWith('.myCss')){
url = url.replace('.myCss', '.css')
res.writeHead(302, {'Location':'/'}) // {1}
// 行{1} 等价于下面两行
// res.statusCode = '302'
// res.setHeader('Location', '/') }

在 index.js 中增加 res.writeHead(302, {'Location':'/'})(行{1}),浏览器输入 http://localhost:3000/1.myCss,页面会重定向到主页。

:没有后端开发经验的学习 node 会比较吃力。比如重定向,我们想到的可能是通过调用一个重定向的方法来实现,而 node 写起来更底层。

302 是临时重定向。301 是永久重定向。请看示例:

// 临时重定向
Request URL: http://localhost:3000/1.myCss
Request Method: GET
Status Code: 302 Found Request URL: http://localhost:3000/1.myCss
Request Method: GET
Status Code: 302 Found // 永久重定向
Request URL: http://localhost:3000/1.myCss
Request Method: GET
Status Code: 301 Moved Permanently Request URL: http://localhost:3000/1.myCss
Request Method: GET
Status Code: 301 Moved Permanently (from disk cache) // {1}

临时重定向,浏览器每次都会去服务器那里;而永久重定向,第二次就不会去服务器那里,而是直接在浏览器端重定向过去(行{1})

自动重启服务

每次修改入口文件,都需要重新启动服务器(执行 node index),非常麻烦。

可以通过 nodemon 来帮助我们自动重启服务。

// 全局安装 nodemon。
$ npm install --global nodemon // 一定要全局安装 nodemon。否则执行 nodemon -v 会报错。
$ nodemon -v // 运行入口文件。
$ nodemon index // {1}

使用 nodemon 非常简单。通过 npm 全局安装后,用 nodemon 代替 node(行{1})运行入口文件即可。

:笔者还尝试了 supervisor,感觉没有 nodemon 好用。比如我输入 let a = (处在一个语法错误的状态)然后保存,supervisor 会退出服务,而 nodemon 只是报错,仍会继续监听。

其他章节请看:

前端学习 node 快速入门 系列

最新文章

  1. bootstrap中的Grid system详解
  2. opengl 读取3ds(stl)文件
  3. H5案例分享:移动端滑屏 touch事件
  4. 在Android开发中如何判读当前设备是否连接网络
  5. JVM调优总结:调优方法
  6. 史上最详细Windows版本搭建安装React Native环境配置 转载,比官网的靠谱亲测可用
  7. [Android实例] 有关spinner 的item问题 谁能给解答下??
  8. 装载:深入理解拉格朗日乘子法(Lagrange Multiplier) 和KKT条件
  9. Qt之SQL数据库
  10. Sky number
  11. MyBatis+Spring 事务管理
  12. js数值使用及数组转json,转化后的json传入后台解析
  13. @SuppressWarnings抑制警告
  14. Angular.js指令
  15. Python学习之路基础篇--09Python基础,初识函数
  16. 74.纯 CSS 创作一台 MacBook Pro
  17. Winform 中写代码布局中遇到的控件遮盖问题
  18. bzoj2839 集合计数
  19. Linux学习笔记之在 CentOS 里下载 RPM 包及其所有依赖包
  20. mybatis generator 双击创建失败

热门文章

  1. leetcode31 下一个排列 字典序
  2. 杭电多校HDU 6656 Kejin Player(概率DP)题解
  3. sql-libs(2) 数字型
  4. Linux 驱动框架---input子系统
  5. 使用 js 实现十大排序算法: 计数排序
  6. flex item default All In One
  7. js 运算符的执行顺序
  8. Android Studio &amp; zh-Hans
  9. SVG 2 &amp; SVG &amp; getPointAtLength &amp; getPathSegAtLength
  10. Object.stringify 循环引用 bug &amp; TypeError: Converting circular structure to JSON