前端学习 node 快速入门 系列 —— 简易版 Apache
其他章节请看:
简易版 Apache
我们用 node 来实现一个简易版的 Apache:提供静态资源访问的能力。
实现
直接上代码。
- demo - static // 静态资源文件夹 - index.html // 主页 - 1.jpg - 1.css - 1.j ad8 s - 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 是永久重定向。请看 56c 示例:
// 临时重定向 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 好用 122f 。比如我输入
let a =(处在一个语法错误的状态)然后保存,supervisor 会退出服务,而 nodemon 只是报错,仍会继续监听。
其他章节请看:
- Html5 学习系列(五)Canvas绘图API快速入门(2)
- Gradle学习系列之(一)——Gradle快速入门
- Gradle学习系列之一——Gradle快速入门(转)
- Gradle学习系列之一——Gradle快速入门
- Gradle学习系列之一——Gradle快速入门(转)
- Gradle学习系列之一——Gradle快速入门
- Gradle学习系列之一——Gradle快速入门
- Vue学习系列 -- vue-router 快速入门
- python学习系列一:python快速入门
- Gradle学习系列之(一)——Gradle快速入门
- Html5 学习系列(五)Canvas绘图API快速入门(1)
- SASS学习系列之四--------- 快速入门
- MyBatis学习总结-MyBatis快速入门的系列教程
- Gradle学习系列之一——Gradle快速入门
- Gradle学习系列之一——Gradle快速入门
- Gradle学习系列之一——Gradle快速入门
- ASP.NET Core快速入门--学习笔记系列文章索引目录
- [新手入门]快速学习 ADO.NET Entity Framework系列文章 #1~#2
- [新手入门]快速学习 ADO.NET Entity Framework系列文章 #3 -- LINQ-to-SQL、EntitySQL、查询产生器方法(Query builder)三种语法
- [新手入门]快速学习 ADO.NET Entity Framework系列文章 #4 -- 数据新增、删除、修改(ObkectContext的 .SaveChange()方法)