1.0 http模块-创建http服务端
// 1.0 导入http模块
const http = require('http')
//2.0 创建服务对象
const server = http.createServer((request,response)=>{
// request 请求报文的对象
// response 相应报文的对象
response.end('hello http server') // 设置响应体
})
// 3.0 监听端口,启动服务
server.listen(9000,()=>{
console.log('服务启动了')
})
// 本机的ip地址 127.0.0.1:9000
注意事项
1.0 响应体如果有中文会出现乱码
// 设置响应头可以解决
// 返回响应的体的内容是html,内容的字符集是utf-8的
response.setHeader('content-type','text/html;charset=utf-8');
response.end('你好 http server') // 设置响应体
2.0 http默认端口是80,https默认端口是443
// 比如 127.0.0.1:80 可以不写80 127.0.0.1
1.1获取请求行和请求头
含义 | 语法 | 重点 |
---|---|---|
请求方法 | request.method | + |
请求协议版本 | request.httpVersion | |
请求路径 | request.url | + |
请求头 | request.headers | + |
url路径 | conts url = require('url') url.parse(request.url).pathname | + |
url查询字符串 | conts url = require('url') url.parse(request.url,true).query 参数true表示结果是一个对象 | + |
demo1
我们再浏览器输入 http://localhost:9000/serarch?name=1&age=2
const http = require('http');
const server = http.createServer((request,response)=>{
console.log(request.method) //GET
console.log(request.httpVersion) // 1.1
console.log(request.url) // /serarch?name=1&age=2
response.setHeader('content-type','text/html;charset=utf-8');
response.end('你好 http server') // 设置响应体
})
server.listen(9000,()=>{
console.log('服务启动了')
})
获取请求头
const http = require('http');
const server = http.createServer((request,response)=>{
console.log(request.headers)
response.setHeader('content-type','text/html;charset=utf-8');
response.end('你好 http server') // 设置响应体
})
server.listen(9000,()=>{
console.log('服务启动了')
})
/*{
host: 'localhost:9000',
connection: 'keep-alive',
'cache-control': 'max-age=0',
'sec-ch-ua': '"Google Chrome";v="113", "Chromium";v="113", "Not-A.Brand";v="24"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
'upgrade-insecure-requests': '1',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36',
accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*!/!*;q=0.8,application/signed-exchange;v=b3;q=0.7',
'sec-fetch-site': 'none',
'sec-fetch-mode': 'navigate',
'sec-fetch-user': '?1',
'sec-fetch-dest': 'document',
'accept-encoding': 'gzip, deflate, br',
'accept-language': 'zh-CN,zh;q=0.9',
cookie: 'Webstorm-d4fcee39=1dc1bd6c-396f-46ab-a7fd-4ede07983e60; Webstorm-f664e712=9938130b-3a8e-4a19-9182-dfcb4736af95; _ga=GA1.1.673861294.166755
8434; JSESSIONID=6B66937DC7508C4EC42FF5102FC16C61'
}*/
注意:
request.headers
将信息转化为一个对象,并将属性名都转化成了【小写】
得到请求的路径和参数
需要导入 url
模块
const http = require('http');
// 导入url模块
const url = require('url')
const server = http.createServer((request,response)=>{
console.log(url.parse(request.url).pathname) // /serarch
let reqData = url.parse(request.url,true).query
console.log(reqData,reqData.name) // { name: '1', age: '2' } 1
response.setHeader('content-type','text/html;charset=utf-8');
response.end('你好 http server') // 设置响应体
})
server.listen(9000,()=>{
console.log('服务启动了')
})
1.2 获取url的路径和参数
第二种方法,上面的是第一种
const http = require('http');
const server = http.createServer((request,response)=>{
console.log(request.url) // /serarch?name=1&age=2
let url = new URL('http://www.baidu.com/search?a=1&b=10')
console.log(url)
response.setHeader('content-type','text/html;charset=utf-8');
response.end('你好 http server') // 设置响应体
})
server.listen(9000,()=>{
console.log('服务启动了')
})
/*URL {
href: 'http://www.baidu.com/search?a=1&b=10',
origin: 'http://www.baidu.com',
protocol: 'http:',
username: '',
password: '',
host: 'www.baidu.com',
hostname: 'www.baidu.com',
port: '',
pathname: '/search',
search: '?a=1&b=10',
searchParams: URLSearchParams { 'a' => '1', 'b' => '10' },
hash: ''
}
*/
const http = require('http');
const server = http.createServer((request,response)=>{
//console.log(request.url) // /serarch?name=1&age=2
// let url = new URL('http://www.baidu.com/search?a=1&b=10')
let url = new URL(request.url,'http://127.0.0:9000')
// 输出路径
console.log(url.pathname) // /serarch
// 获取参数
console.log(url.searchParams.get('age')) // 2
response.setHeader('content-type','text/html;charset=utf-8');
response.end('你好 http server') // 设置响应体
})
server.listen(9000,()=>{
console.log('服务启动了')
})
2.0 http请求练习
要求:
1.0 get类型 请求地址 /login 响应体 登录界面
2.0 get类型 请求地址 /reg 响应体 注册界面
const http = require('http')
const server = http.createServer((req,res)=>{
res.setHeader('content-type','text/html;charset=utf-8');
let url = new URL(req.url,'http://127.0.0.1:9000')
console.log(url)
let name = url.pathname
if(name == '/login'){
res.end('登录页面')
}else if(name == '/reg'){
res.end('注册页面')
}else{
res.end('未知请求')
}
})
server.listen(9000,()=>{
console.log('练习http')
})
3.0 设置http相应报文
作用 | 语法 |
---|---|
设置相应状态码 | response.statusCode |
设置相应状态描述 | response.statusMessage (很少用) |
设置相应头信息 | response.setHeader('名字',‘值’) |
设置响应体 | response.write() response.end() |
const http = require('http')
const server = http.createServer((req,res)=>{
res.setHeader('content-type','text/html;charset=utf-8');
// 1.0 设置响应状态码
res.statusCode = 203;
// 2.0 响应状态的描述
res.statusMessage = 'iiii ni' // HTTP/1.1 203 iiii ni
// 3.0 响应头
res.setHeader('content-type','text/html;charset=utf-8')
res.setHeader('Server','node.js') // 自定义的
res.setHeader('myHeader','hello') // 自定义的
res.setHeader('test',[1,2,3]) // 设置多个同名响应头
// 4.0 响应体的设置
res.write('love');
// 可以有很多个
// res.write('love2');
// res.write('love3');
// res.write('love4');
// end 方法必须有一个
res.end('end') // 设置响应体
})
server.listen(9000,()=>{
console.log('练习http')
})
3.1http响应练习
要求:
响应一个4行3列的表格,隔行换色,并且点击单元格高亮显示
const http = require('http')
const fs = require('fs')
const path = require('path')
const server = http.createServer((req,res)=>{
res.setHeader('content-type','text/html;charset=utf-8');
// 同步读取文件
let data = fs.readFileSync('./serve/1-table.html')
// 可以用绝对路径
// let data = fs.readFileSync(__dirname + '/serve/1-table.html')
// 用path.resolve 方法 另外的绝对路径
// let url1 = path.resolve(__dirname,'/serve/1-table.html')
// let url2 = path.resolve(__dirname,'./serve/1-table.html')
// let url3 = path.resolve(__dirname,'serve/1-table.html')
// console.log(url1,url2,url3)
// D:\serve\1-table.html 所以这个不能用
// D:\newNode\node-1\serve\1-table.html
// D:\newNode\node-1\serve\1-table.html
// res.write(data); // 这俩都行
res.end(data) // 设置响应体
})
server.listen(9000,()=>{
console.log('练习http')
})
serve/1-table.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
table,td{
/*合并边框*/
border-collapse: collapse;
}
/*奇数*/
table tr:nth-child(odd){
background-color: palegoldenrod;
}
/*偶数*/
table tr:nth-child(even){
background-color: palegreen;
}
tr,td{
padding: 30px 40px;
border:1px solid #ccc;
}
</style>
</head>
<body>
<table>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</table>
<script>
let tds = document.querySelectorAll('td')
console.log(tds)
tds.forEach((item,index)=>{
item.onclick = function(){
this.style.background = '#f65748'
}
})
</script>
</body>
</html>
重点
上面的html都在一个页面里面,如果把js和css拆分出去,页面是会出错了,因为我们的ndoejs里面的响应写的有问题,需要修改一下
// res.setHeader('content-type','text/html;charset=utf-8'); 一定要去掉
const http = require('http')
const fs = require('fs')
const path = require('path')
const server = http.createServer((req,res)=>{
// res.setHeader('content-type','text/html;charset=utf-8'); 一定要去掉
// 获取url 路径
let { pathname } = new URL(req.url,'http://127.0.0.1:9000')
console.log(pathname)
if(pathname == '/'){
let data = fs.readFileSync(path.resolve(__dirname ,'serve/1-table.html'))
console.log(path.resolve(__dirname ,'serve/1-table.html'))
res.end(data) // 设置响应体
}else if(pathname == '/table.css'){
let data = fs.readFileSync(path.resolve(__dirname ,'serve/table.css'))
console.log(path.resolve(__dirname ,'serve/table.css'))
res.end(data) // 设置响应体
}else if(pathname == '/index.js'){
let data = fs.readFileSync(path.resolve(__dirname ,'serve/index.js'))
res.end(data) // 设置响应体
}else{
res.statusCode = 404
res.end('404 not found') // 设置响应体
}
})
server.listen(9000,()=>{
console.log('练习http')
})
这样写麻烦死了我才两个资源都这样了要是很多咋办,优化
3.2搭建静态资源服务
我们新建一个结构
serve
-- css
----table.css
-- js
----table.js
table.html
const http = require('http')
const fs = require('fs')
const path = require('path')
const server = http.createServer((req,res)=>{
// res.setHeader('content-type','text/html;charset=utf-8');
// 获取url 路径
let { pathname } = new URL(req.url,'http://127.0.0.1:9000')
// 拼接路径
let filePath = path.resolve(__dirname , `serve/${pathname}`)
console.log(pathname,filePath)
// 异步读取
fs.readFile(filePath,(err,data)=>{
if(err){
res.statusCode = 500
res.end('服务器错误')
return
}
res.end(data)
})
})
server.listen(9000,()=>{
console.log('练习http')
})
优化一下文件读取的错误处理
// 异步读取
fs.readFile(filePath,(err,data)=>{
if(err){
res.setHeader('content-type','text/html;charset=utf-8');
switch (err.code){
case 'ENOENT':
res.statusCode = 404
res.end('404 not Found')
break;
case 'EPERM':
res.statusCode = 403
res.end('404 Forbidden')
break;
default:
res.statusCode = 500
res.end('位置错误')
}
return
}
res.end(data)
})
3.3 相对路径的两种写法
1.0 ./css/index.css
2.0 css/index.css
3.4资源类型
记住下载的就行
response.setHeader('content-type','application/octet-stream')
余生还很长,别把一切都提前交代了,一边走一边欣赏风景一切都要慢慢来