前后端交互流程
大后端
用户
- > 地址栏(http[s]请求)
- -> web服务器(收到)
- - > nodejs处理请求(返回静态、动态)
- ->请求数据库服务(返回结果)
- ->nodejs(接收)
- ->node渲染页面
- ->浏览器(接收页面,完成最终渲染)
大前端
用户
- > http[s]请求
- -> web服务器(收到)
- - > nodejs处理请求(返回静态、动态)
- ->请求数据库服务(返回结果)
- ->nodejs(接收)
- ->返回给前端(渲染)
- ->浏览器(接收页面,完成最终渲染)
实现
引入http模块
let http = require('http')
创建web服务 返回http对象
let app = http.createServer((req,res)=>{
req 请求体 浏览器->服务器
req.url 地址 提取地址栏数据
req.on('data') 提取非地址栏数据 所有的http[s]都会触发end事件
req.on('end')
res 响应 服务器->浏览器
res.writeHead(200,{'Content-Type':'text/html;charset=utf-8'});响应头设置
res.write(字符/数据<string><buffer>) 返回数据
res.end() 结束响应 必须
})
监听服务器
app.listen(端口,[地址],[回调])
FS模块
磁盘操作,文件操作
读取
fs.readFile('文件路径',[编码方式],(err,data)=>{})
[err]: err 错误 ,null没有错误
[data]: 数据流,buffer流
变量 = fs.readFileSync('文件路径')
处理错误
try{要排错的代码}catch(e){}
更改名字
fs.renameSync('改前','改后');
删除
fs.unlinkSync('文件路径')
静态资源托管
前端资源请求
<a href=".."></a>
<img src="..."/>
后端资源读取
fs.readFile(文件名,[编码方式],回调(err,data));
接口实现
前端
表单:get/post/put/delete/…
js: ajax/jsonp
后端
处理方式:http[s]
address: req.url
抓取 get请求的数据 切字符 | url模块
!address: req.on('data',(chunk)=>{CHUNK==每次收到的数据buffer})
req.on('end',()=>{ 接收完毕 切字符 querystring })
URL模块
作用
处理URL型的字符串
用法
url.parse(str,true) 返回 对象 true处理query为对象
str -> obj 返回 对象 true
protocol: ‘http:’, 协议
slashes: true, 双斜杠
auth: null, 作者
host: ‘localhost:8002’, 主机
port: ‘8002’, 端口
hostname: ‘localhost’, baidu
hash: ‘#title’, 哈希(锚)
search: ‘?username=sdfsdf&content=234234’, 查询字符串
query: ‘username=sdfsdf&content=234234’, 数据
pathname: ‘/aaa’, 文件路径
path: ‘/aaa?username=sdfsdf&content=234234’, 文件路径
href: 'http://localhost:8002/aaa?username=sdfsdf&content=234234#title’
url.format(obj) 返回字符
obj -> str 返回str
querystring模块
作用
处理查询字符串 如:?key=value&key2=value2
用法
querystring.parse(str) 返回对象
querystring.stringify(obj) 返回字符串
资源托管
//1.引入相应的原生模块、依赖
let http = require("http")
let fs = require("fs")
//2.实例化http对象(服务器对象)
let app = http.createServer((req,res)=>{
//排除 /favicon.ico的请求
if(req.url.indexOf("/favicon.ico") === -1){
//需要判断要读取的是动态资源(接口api)还是静态资源
if(req.url.indexOf("/api") !== -1){ //处理接口
console.log("处理/api开头的动态接口",req.url)
}else{ //处理静态资源 /index.html
try {
let path = req.url === "/" ? "/index.html" : req.url;
let html = fs.readFileSync("./www"+path)
//直接将html结果返回给浏览器
res.write(html)
} catch (error) {
let html = fs.readFileSync("./www/nopage.html")
res.write(html)
}
}
}
res.end()
})
//监听服务器
app.listen(3000)
处理接口
//1.引入相应的原生模块、依赖
let http = require("http")
let fs = require("fs")
let url = require("url")
let querystring = require("querystring")
//2.实例化http对象(服务器对象)
let app = http.createServer((req,res)=>{
//排除 /favicon.ico的请求
if(req.url.indexOf("/favicon.ico") === -1){
//需要判断要读取的是动态资源(接口api)还是静态资源
if(req.url.indexOf("/api") !== -1){ //处理接口
//处理地址栏的数据
let urlObj = url.parse(req.url,true)
console.log(urlObj.query)
//非地址栏的数据
let noAddressData = "" //存放非地址栏的数据
req.on("data",chunk=>{ //chunk代表抓取的一片数据,data事件内部会频繁的触发
noAddressData += chunk
})
req.on("end",()=>{ //数据已经全部接受完毕
console.log("非地址栏的数据:",querystring.parse(noAddressData))
})
}else{ //处理静态资源 /index.html
try {
let path = req.url === "/" ? "/index.html" : req.url;
let html = fs.readFileSync("./www"+path)
//直接将html结果返回给浏览器
res.write(html)
} catch (error) {
let html = fs.readFileSync("./www/nopage.html")
res.write(html)
}
}
}
res.end()
})
//监听服务器
app.listen(3000) //3000端口号,建议不要写 1024 以及之前的防止端口冲突