美文网首页
node.js学习日记day2

node.js学习日记day2

作者: Reedcpp | 来源:发表于2020-09-11 13:18 被阅读0次

nodejs-02

服务器的优化

  1. 对图片、json等数据的文件头进行修改(用到mime.json文件)
  2. 使用Nodejs提供的同步读取文件方法来对文件进行读取操作

原先写入Content-Type的代码: 类型少,无法识别json、js、png等格式

exports.getMime=function(extname){
    switch(extname){
        case '.html': return 'text/html'
        case '.css': return 'text/css'
        case '.js': return 'text/javascript'
        default:
            return 'text/html'
    }
}

mime.json文件:(部分) 种类齐全,通过fs模块读取,并且使用JSON.parse方法转换成对象,然后使用[键]获取到对应的Content-Type

{ ".323":"text/h323" ,
  ".3gp":"video/3gpp" ,
  ".aab":"application/x-authoware-bin" ,
  ".aam":"application/x-authoware-map" ,
  ".aas":"application/x-authoware-seg" ,
  ".acx":"application/internet-property-stream" ,
  ".ai":"application/postscript" ,
  ".aif":"audio/x-aiff" ,
}
// 因为文件操作是异步的,所以可以让下面的方法return一个Promise
exports.getFileMime = function(extname){
    return new Promise((resolve, reject)=>{
        fs.readFile('./data/mime.json', (err, data)=>{
            if(err){
                reject(err)
                return
            }
            // 对读取进来的json文件parse
            let mime = JSON.parse(data.toString())
            // 查找相对应的Content-Type
            resolve(mime[extname])
        })
    })
}

app.js中写入contenttype:

// 使用了async和await,因为前面exports的方法是异步方法
fs.readFile(`./static${pathName}`, async (err, data) => {
    if (err) {
        res.writeHead(404, { 'Content-Type': 'text/html;charset="utf-8"' })
        res.end('404')
    }
    //过滤文件,使不同的静态文件都可以以正确的文件头渲染
    let mime = await common.getFileMime(extName)
    res.writeHead(200, { 'Content-Type': ''+mime+';charset="utf-8"' })
    res.end(data)
})

另外还可以使用同步的方法来读取mime.json文件:


exports.getFileMimeSync = function(extname){
    // fs模块中提供的同步读取文件方法
    let data = fs.readFileSync('./data/mime.json')
    let mime = JSON.parse(data.toString())
    return mime[extname]
}

这样就可以不使用async和await读取到文件

fs.readFile(`./static${pathName}`, (err, data) => {
            if (err) {
                res.writeHead(404, { 'Content-Type': 'text/html;charset="utf-8"' })
                res.end('404')
            }
            //过滤文件,使不同的静态文件都可以以正确的文件头渲染 
            // nodejs提供的同步读取文件的方法,这里可以不使用async和await就可以获取到文件
            let mime = common.getFileMimeSync(extName)
            res.writeHead(200, { 'Content-Type': ''+mime+';charset="utf-8"' })
            res.end(data)
        })

web服务和静态路由

路由

路由(Routing)是由一个URL和一个特定的http方法(get post)组成的,涉及到应用如何响应客户端对某个网站节点的访问,通俗来说路由指的就是针对不同请求的url,处理不同的业务逻辑

比如说当我们需要访问登陆页面,我们可以访问 http://127.0.0.1:8111/login (这和http://127.0.0.1:8111/login.html是不一样的)

先把之前编写的创建服务器的代码进行封装

在routes.js中:

//  把创建服务器的相关操作封装好,减少app.js的代码量
exports.static = function (req, res, staticPath) {
    // 1. 获取地址
    let pathName = url.parse(req.url).pathname
    // 判断url是否为/ 如果是的话就把'/index.html'赋给pathName,强行跳转index
    pathName = pathName === '/' ? '/index.html' : pathName
    // 通过path模块获取url的后缀名
    let extName = path.extname(pathName)
    // 2. 通过fs模块读取文件,
    if (pathName !== '/favicon.ico') { // 先过滤掉其他无关的url
        // 把获取到的url拼接到文件读取流的参数中,读取HTML文件
        try {
            // 同步读取
            let data = fs.readFileSync(`./${staticPath}${pathName}`)
            //过滤文件,使不同的静态文件都可以以正确的文件头渲染
            if (data) {
                let mime = getFileMimeSync(extName)
                res.writeHead(200, { 'Content-Type': '' + mime + ';charset="utf-8"' })
                res.end(data)
            }
        } catch (error) {}
    }
}

然后在app.js中引用这个模块,并且:

const routes = require('./module/routes')
routes.static(req, res, 'static')

下面是路由的实现方式

  1. 首先需要对req.url进行解析

    let pathname = url.parse(req.url).pathname
    
  2. 然后对不同的路径进行判断

    if (pathname === '/login') {
            res.writeHead(200, { 'Content-Type': 'text/html;charset="utf-8"' })
            res.end('login')
        } else if (pathname === '/register') {
            res.writeHead(200, { 'Content-Type': 'text/html;charset="utf-8"' })
            res.end('register')
        } else if (pathname === '/admin') {
            res.writeHead(200, { 'Content-Type': 'text/html;charset="utf-8"' })
            res.end('admin')
        } else {
            res.writeHead(200, { 'Content-Type': 'text/html;charset="utf-8"' })
            res.end('404')
        }
    

此处需要注意的是,当我们封装好的创建服务器代码中如果包含异步的方法,可能会导致首页无法加载完成,所以可以使用同步的方法来对static路径中的资源进行读取,确保读取完成资源后再进行路由判断

模板引擎

本课程使用ejs模板引擎

使用npm命令安装ejs模板引擎,安装完成后使用ejs编写页面

在app.js中有如下两条数据

let msg = '我是模拟数据'
    let list = [
        {'title': '1'},
        {'title': '2'},
        {'title': '3'},
        {'title': '4'}
    ]

使用模板引擎把它们渲染到页面上:

if (pathname === '/login') {
        /**
         * 要渲染的模板
         * 要渲染进去的参数(对象
         * 回调函数
         */
        ejs.renderFile('./views/login.ejs', {msg, list}, (err, data) => {
            res.writeHead(200, {'Content-Type': 'text/html;charset="utf-8"'})
            res.end(data)
        })
    }

在login.ejs中:

<body>
    <h2>ejs</h2>
    <h3><%= msg %></h3>
    <br>
    <ul>
        <%for(var i=0;i<list.length;i++){%>
            <li><%=list[i].title%></li>
        <%}%>
    </ul>
</body>

这样就可以把数据动态渲染在页面上

GET&&POST...

在客户端和无武器之间进行请求响应时,用到最多的是get和post

  • get用于从制定的资源请求数据

  • post用于向指定的资源提交要被处理的数据

使用get来获取url中的相关信息(使用url模块中的parse方法,并且获取其中的query):

const url = require('url')
if (pathname === '/news'){
        let query = url.parse(req.url, true).query
        // 可以通过req.method来获取请求类型
        console.log(req.method)
        console.log(query)
        res.writeHead(200, {'Content-Type': 'text/html;charset="utf-8"'})
        res.end('query')
}

使用post请求提交数据:

模板中的表单

<body>
<form action="/doLogin" method="post">
    <input type="text" name="username"/>
    <br>
    <input type="password" name="password"/>
    <br>
    <input type="submit" value="submit">
</form>
</body>

访问的login路由

if (pathname === '/login') {
        //post演示,渲染模板
        ejs.renderFile('./views/form.ejs', {}, (err, data) => {
            res.writeHead(200, {'Content-Type': 'text/html;charset="utf-8"'})
            res.end(data)
        })
    }

访问的doLogin路由(原生js获取post数据):

if (pathname === '/doLogin') {
        let postData = ''
        // on读取数据是通过流方式来读取,所以需要拼接,chunk是读取的片段
        req.on('data', chunk=>{
            postData += chunk
        })
        req.on('end', ()=>{
            console.log(postData)
            res.end(postData)
        })
        res.writeHead(200, {'Content-Type': 'text/html;charset="utf-8"'})
 }

输出结果:

E:\nodejs\demo12>node app.js
http://127.0.0.1:8111/
username=2017123456&password=123123

相关文章

  • node.js学习日记day2

    nodejs-02 服务器的优化 对图片、json等数据的文件头进行修改(用到mime.json文件) 使用Nod...

  • node.js学习day2

    NodeJS的作者说,他创造NodeJS的目的是为了实现高性能Web服务器,他首先看重的是事件机制和异步IO模型的...

  • Node.js学习之路day2

    1. node Buffer 处理tcp,文件等流的时候,必须要用到二进制数据,node的Buffer就是一个专门...

  • 2019-08-07 Day2——DFL

    Day2 学习笔记

  • Day2- Sleep Helps Us Learn &

    打卡日记 Day2—— Sleep Helps Us Learn & Tips for better slee...

  • 2020-10-25

    day2 . 的学习笔记

  • 2018-12-06

    Day2 20181205 工作日记 被夸奖了,但是,还是觉得好难

  • 晨间日记

    2019.8.3晴周甜的晨间日记 30min 晨间日记的奇迹 2019.8.3周甜的晨间日记day2/100 A区...

  • 赞美日记

    #爱wen•赞美日记# Day2/终身 [爱心]谢谢你,我爱你[爱心]

  • 2019-05-28

    标题:修心课之曾国藩的四个习惯Day2 字数: 正文: 名人曾国藩,也有普通人可以学习培养的习惯。从名人的日记中,...

网友评论

      本文标题:node.js学习日记day2

      本文链接:https://www.haomeiwen.com/subject/knnvektx.html