静态资源
服务器不需要处理,可以直接响应给客户端的资源就是静态资源,例如CSS、JavaScript、image文件。
https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png
const http = require('http');
const url = require('url');
const app = http.createServer();
const path = require('path');
const fs = require('fs');
// 把第三方模块引进来
const mime = require('mime');
// 对服务器对象做一个监听
app.on('request',(req,res) =>{
// 获取用户请求路径
let pathname = url.parse(req.url).pathname;
pathname = pathname == '/' ? '/default.html' :pathname;
// 把用户的请求路径转化为文件真实的物理路径
// res.end('ok');
// 将用户的请求路径转换为实际的服务器硬盘路径
let realPath = path.join(__dirname, 'public' + pathname);
// res.end(path.join(__dirname, 'public' + pathname));
// __dirname + 'public' + pathname
// console.log(mime.getType(realPath))
let type = mime.getType(realPath)
// 如果文件读取成功 error是空,如果文件读取成功result就是文件内容
// 如果文件读取失败 那error就是一个失败的对象存储着失败的信息
// result它的值会是空
// 读取文件严谨需要错误处理
fs.readFile(realPath,(error,result) =>{
// 如果文件读取失败
if(error != null) {
// res.writeHead('404',{
// 'content-type':'text/html; charset = "utf-8"'
// })
res.writeHead(404,{
'content-type':'text/html; charset="utf-8"'
});
res.end('文件读取失败');
return;
}
// mime 第三方模块可以根据你当前的请求路径分析出资源的类型
// 然后把类型通过返回值的方式返回
res.writeHead(200,{
'content-type':type
})
// 文件读取成功 result就是读取文件内容
res.end(result)
})
fs.readFile(realPath, (error,result) =>{
res.end(result)
});
});
app.listen(3000);
console.log('服务器启动成功')
动态资源
相同的请求地址不同的响应资源,这种资源就是动态资源
https://cn.vuejs.org/v2/api/#%E9%80%89%E9%A1%B9-%E6%95%B0%E6%8D%AE
https://cn.vuejs.org/v2/api/#%E9%80%89%E9%A1%B9-DOM
如果希望在服务器端这些文件能够被访问到就必须实现静态资源访问功能
同步API,异步API
//路径拼接
const public = path.join(__dirname,'public');
//请求地址解析
const urlobj = url.parse(req.url);
//读取文件
fs.readFile('./demo.txt,'utf8',(err,result) =>{
console.log(result);
});
同步API:只有当前API执行完成后,才能继续
console.log('before');
console.log('after');
异步API:当前API的执行不会阻塞后续代码的执行
console.log('before');
setTimeout(
() => {console.log('last');
},2000);
console.log('after');
console.log('before');
// 开启定时器
setTimeout(function(){
console.log('last')
},2000)
console.log('after');
代码的执行结果是先在控制台中输出before然后再输出after,两秒钟之后再输出last,也就是说定时器代码就算在最后一个console.log(‘after’)前面,但是程序在执行到定时器代码的时候并没有等待定时器代码完成再执行最后一个console.log方法。
在上面的代码中 定时器setTimeOut就是异步API,程序不需要等待异步API执行完之后再继续执行后面的代码。也就是说异步API不会阻塞后面代码的执行,在nodejs当中,异步API可以说是无处不在,掌握nodejs中的异步编程是非常非常重要的。
同步API,异步API的区别(获取返回值)
同步API可以从返回值中拿到API执行的结果,但是异步API是不可以的
//同步
function sum (n1,n2){
return n1 + n2;
}
const result = sum (10,20);
//异步
function getMsg(){
setTimeout(function(){
return { msg: 'Hello Node.js'}
},2000);
}
const msg = getMsg();
回调函数
自己定义函数让别人去调用
//getData函数定义
function getData (callback){
//getData 函数调用
getData (() =>{});
}
function getData (callback) {
callback('123')
}
getData(function (n) {
console.log('callback函数被调用了')
console.log(n)
});
function getMsg(callback){
setTimeout(function(){
callback({
msg:'hello node.js'
})
},2000)
// 异步函数不会阻塞后续代码的执行后续代码就是return undefined;
}
getMsg(function(data){
console.log(data);
});
// const msg = getMsg();
// console.log(msg);
同步API,异步API的区别(代码执行顺序)
同步API从上到下依次执行,前面代码会阻塞后面代码的执行
for(var i = 0; i < 1000000; i++){
console.log(i);
}
console.log('for循环后面的代码');
同步API从上到下依次执行,前面的代码会阻塞后面代码的执行。
异步API不会等待API执行完成后再向下执行代码
console.log('代码开始执行')
setTimeout(function(){
console.log('2s')
},2000)
setTimeout(function(){
console.log('0s')
},0)
console.log('代码结束执行')
nodejs会从上到下依次执行代码,遇到同步代码把它拿到同步代码执行区执行,遇到异步API他不会执行而是放到异步代码执行区当中,当代码中所有同步代码执行完之后再到异步代码执行区依次执行代码,当异步代码执行完成之后系统会去系统回调函数队列去找异步API所对应的回调函数,然后把回调函数同步放到同步代码执行区当中再去执行它。这就是异步API的执行顺序。