一、背景
由于我们无法事先得知一个.html文件中会引用多少个静态资源(.png, .css, .js....),所以,我们不能像处理某个页面一样去处理它们。
我们的解决办法是:
- 把所有的静态资源(.html,.png,.css,.js)全放在一个**指定的目录**里;
- 收到用户的请求之后,去指定的目录下去找对应的文件
- 找到,把内容读出来返回给用户。
- 找不到,报404。
二、准备工作
2.1创建目录
|-public
|-public/index.html
|-public/stye.css
|-public/1.png
|-server.js
2.2代码
我们在server.js操作
目标:访问http://localhost:8085/index.html ------>public/index.html
访问http://localhost:8085/style.css ------>public/style.css
先创建一个基本的服务器
//导入核心模块
const http = require('http')
//创建http服务,参数是一个回调函数,当接收到http请求时,被调用
//回调函数有两个参数:req 客户端的请求 res 本次请求的响应
const server= http.createServer((req,res)=>{
//向客户端发送内容,并结束本次响应
res.end('ok')
})
//监听端口请求
server.listen(8888)
实现目标 :如果 req.url 要访问的文件在public能找到,就读出来,返回
const http = require('http')
const fs = require('fs')
const path = require ('path')
const server = http.createServer((req, res) => {
// 如果直接http://localhost:8085 ===> req.url 就是 /,这时,希望它去加载 /index.html
// const url = req.url === '/' ? '/index.html' : req.url
// 如果 req.url 要访问的文件在public能找到,就读出来,返回
const filePath = path.join(__dirname,'public', req.url)
fs.readFile(filePath,(err,data)=>{
if(err){
res.statusCode = 404
res.end('not found')
}else {
res.end(data)
}
})
// if(filePath存在){
// 读出来,返回
// } else{
// 返回404
// }
// res.end(filePath)
})
server.listen(8085)
优化---省略后缀名
// 如果直接http://localhost:8085 ===> req.url 就是 /,这时,希望它去加载 /index.html
const url = req.url === '/' ? '/index.html' : req.url
const filePath = path.join(__dirname,'public', url)
优化:设置响应头中的 content-type
“策略模式”
.png --> 'image/png'
.html --> 'text/html;charset=utf8'
.js --> 'application/javascript;charset=utf8'
.css --> 'text/css;charset=utf8'
// 获取后缀名
const extName = path.extname(filePath)
console.log('本次请求的资源', extName, filePath)
// 设置响应头中的content-type
if(extName === '.png') {
res.setHeader('content-type', 'image/png')
} else if(extName === '.html') {
res.setHeader('content-type', 'text/html;charset=utf8')
}else if(extName === '.js') {
res.setHeader('content-type', 'application/javascript;charset=utf8')
}else if(extName === '.css') {
res.setHeader('content-type', 'text/css;charset=utf8')
}
优化 如果再有别的后缀名就得重复设置了,所以我们可以在外面定义一个对象
const obj = {
".png":"image/png",
".jpg":"image/jpg",
".html":"text/html;charset=utf8",
".js":"application/javascript;charset=utf8",
".css":"text/css;charset=utf8"
}
这样就可以解放上面if,eles代码了,改变为
以后还有别的后缀 就可以在对象中追加
if(obj[extName]) {
res.setHeader('content-type', obj[extName])
}