Node基础知识二

123 阅读5分钟

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')

余生还很长,别把一切都提前交代了,一边走一边欣赏风景一切都要慢慢来

qdysh.png