监听 http 请求
const http = require('http')
const server = http.createServer(() => {
console.log('已经收到 http 请求')
})
server.listen(3000)
console.log('http 请求已经被监听,3000 端口,请访问 http://localhost:3000')
使用 req 和 res
const http = require('http')
// req Request, res Response
const server = http.createServer((req,res) => {
const url = req.url
console.log('url is:', url)
res.end('hello world')
})
server.listen(3000)
console.log('http 请求已经被监听,3000 端口,请访问 http://localhost:3000')
路由包含什么
- 定义 method,如 GET/POST 等
- 定义 url 规则,如 /api/list 和 /api/create
- 定义输入(Request body) 和输出(Response body)格式
路由是什么
- router
- 服务端的入口规则
- 和前端的约定
路由和 url
- 路由是规则,url 是具体的形式
nodejs 定义路由
- 从 req 中获取 url 和 method
- 判断 method 是否符合
- 看 url 是否符合规则
模拟一个 GET,POST 路由
const http = require('http')
const server = http.createServer((req, res) => {
const url = req.url
const path = url.split('?')[0]
const method = req.method
// console.log('url is:', url)
// console.log('method is:', method)
if (path === '/api/list' && method === 'GET') {
res.end('this is list router')
}
if (path === '/api/create' && method === 'POST') {
res.end('this is create router')
}
res.end(404)
})
querystring
什么是 querystring
- http://xxx.com/list.html?keyword=nba&lang=en&a=100
- url 问号 ? 后面的都是 querystring(也叫 url 参数)
- & 分割,key=value 形式,可继续扩展
querystring 的作用
- 动态网页的基石(web1.0 -> web2.0)
如何利用 querystring 实现动态网页
- 服务端拿到 querystring
- 根据不同的 querystring,返回不同的内容
- 即变化 querystring,就是变换内容(只要服务端支持)
querystring 举例
const http = require('http')
const server = http.createServer((req, res) => {
const url = req.url
const path = url.split('?')[0]
const queryStr = url.split('?')[1]
const method = req.method
const query = {}
queryStr && queryStr.split('&').forEach(item => {
const [key, value] = item.split('=')
query[key] = value
})
if (path === '/api/list' && method === 'GET') {
if (query.filterType === 2) {
res.end('this is list router, my')
return
} else {
res.end('this is list router, all')
return
}
}
if (path === '/api/create' && method === 'POST') {
res.end('this is create router')
return
}
res.end('404')
})
server.listen(3000)
用 nodejs 自带的 querystring 解析变量
const http = require('http')
const querystring = require('querystring')
const server = http.createServer((req, res) => {
const url = req.url
const path = url.split('?')[0]
const queryStr = url.split('?')[1]
const method = req.method
const query = querystring.parse(queryStr)
if (path === '/api/list' && method === 'GET') {
if (query.filterType === '2') {
res.end('this is list router, my')
return
} else {
res.end('this is list router, all')
return
}
}
if (path === '/api/create' && method === 'POST') {
res.end('this is create router')
return
}
res.end('404')
})
server.listen(3000)
论:结构化与非结构化
- 结构化的数据,易于通过程序访问和分析,如对象和数组
- 非结构化的数据,不易通过程序分析,如字符串
- 编程中的数据,都尽量结构化
设置状态码,Content-type 和 body
const http = require('http')
const querystring = require('querystring')
const server = http.createServer((req, res) => {
const url = req.url
const path = url.split('?')[0]
const queryStr = url.split('?')[1]
const method = req.method
const query = querystring.parse(queryStr)
if (path === '/api/list' && method === 'GET') {
const data = {
errno: 0,
data: [
{ name: '张三', content: '评论1' },
{ name: '李四', content: '评论2' }
]
}
res.writeHead(400, { 'Content-type': 'application/json' })
res.end(JSON.stringify(data))
return
}
if (path === '/api/create' && method === 'POST') {
const data = {
errno: 0,
message: '评论成功'
}
res.writeHead(200, { 'Content-type': 'application/json' })
res.end(JSON.stringify(data))
return
}
res.writeHead(404, { 'Content-type': 'text/plain' })
res.end('404 Not Found')
})
server.listen(3000)
res 返回 html
const http = require('http')
const server = http.createServer((req, res) => {
res.writeHead(404, { 'Content-type': 'text/html' })
res.end(`
<!DOCTYPE html>
<html>
<head>
<title>404 Not Found</title>
</head>
<body>
404 Not Found
</body>
</html>
`)
})
server.listen(3000)
req 接收 body 中的数据
const http = require('http')
const querystring = require('querystring')
// req Request, res Response
const server = http.createServer((req, res) => {
// console.log('已经收到 http 请求')
const url = req.url
const path = url.split('?')[0]
const queryStr = url.split('?')[1]
const method = req.method
const query = querystring.parse(queryStr)
if (path === '/api/create' && method === 'POST') {
const contentType = req.headers['content-type']
let bodyStr = ''
req.on('data', chunk => { // 监听 data 时间获取流数据
bodyStr += chunk.toString()
})
req.on('end', () => { // 监听 end 事件知道流结束了
if (contentType === 'application/json') {
const body = JSON.parse(bodyStr)
console.log(body)
}
res.end('接收完毕')
})
return
}
res.writeHead(404, { 'Content-type': 'text/plain' })
res.end('404 Not Found')
})
server.listen(3000)
cookie 的操作
const http = require('http')
const server = http.createServer((req, res) => {
// 设置 cookie
res.setHeader('Set-Cookie', 'b=200')
// 接收 cookie
const cookieStr = req.headers.cookie
console.log('cookie', cookieStr)
// 结构化 cookie
const cookieObj = {}
cookieStr.split(';').forEach(cookieItem => {
const [key, value] = cookieItem.trim().split('=')
cookieObj[key] = value
})
console.log('cookieObj', cookieObj)
res.end('cookie test')
})
server.listen(3000)
表单验证插件
validator.js