node 第三章

01 http动静分离将js DOM css img进行分离

加载静态资源 html css img等 因为静态资源不会发生改变可以进行缓存

import http from 'http'

import fs from 'fs'

import path from 'path'

import mime from 'mime'

const server = http.createServer((req,res)=>{

  const {method,url} = req

  if(method==='GET'&& url.startsWith('./static')){ // 处理静态资源

       const staticPath = path.join(process.cwd(),url)

        fs.readFile(staticPath,(err,data)=>{

            if(err) {

                res.writeHead(404,{
                    
                       'content-type':'text/plain'
                })

                res.end('not found')

            }else{

            const type = mime.getTpye(staticPath)

            res.writHead(200,{

                'content-type':type,

                'cache-control':'public, max-age=3600' // 设置缓存时间
             })
        
            res.end(data)
        
            }

        
        })
        
   }

   if((method==='post' || method ==='get') && url.startsWith('/api')){ // 处理动态资源

        // 正常处理接口就可以了
        
    }


})

02 邮件服务

需要安装两个库 js-yaml nodemailer

npm i js-yaml

npm i nodemailer


第一步 引入 

import nodemailer from 'nodemailer

import yaml from 'js-yaml'

import httpfrom 'node:http'

imoport fs from 'node:fs'

import url from"node:url

// 初始化邮件服务

const transport = nodemailer.createTransport({

 service:'qq',

 host:'smtp.qq.com',

 port:465,

 secure:true,

 auth:{

   user:'',邮箱账号

   pass:'' 密码 授权码  // 需要看开发文档去生成
 }

})

const

http.createServer(async(req,res)=> {

  const {pathname}= url.parse(req.url)

  const {method}=req

  if(method==='post'&&pathname=='/send/mail'} {

        // 发送邮件

        transport.sendMail({

            to:'收件人',

            from:'发件人',

            subject:'主题',

            text:'内容'
        })

        res.sed('ok')
  }

}).listen(3000,()=>{

console.log('listening on port 3000')

})

 

03 express

第一步 安装 express  log4js

import express = from 'express'

const app = express()

app.use(express.json()) // 解析post参数的中间件


app.get('/',(req,res)=>{


console.log(req.query) // 接收前端参数


 res.send('hello')

})


app.get('/detail/:id',(req,res)=>{

    console.log(req.params.id)

})

app.post('/login',(req,res)=>{

console.log(req.body) // 接收post参数

})




app.listen(3000,()=>{

console.log('http://localhost:3000')

})

04 express路由模块化

demo/src/list.js


import  express from 'express'


const router = express.Router()

router.get('/register',(req,res)=>{

    console.log('register')

})

export default router

----------------------------------------------

app.js 文件代码

import list from './src/list.js'

app.use('/list',list)

05 中间件的编写

demo/middleware/logger.js


import log4js from 'log4js'

控制台输出日志与文件

log4js.configure({

    appenders:{

        out:{

        type:'stdout',

        layout:{type:'colored'}

        }

    },
    
    file:{

        filename:'logs/server.log',

        type:'file'
    },

    categories:{

     default:{


        appenders:['out','file'].

        level:'debug'
     }
    }

})

const logger = log4js.getLogger('default')

// 每个请求都会经过中间件

const LoggerMiddleware = (req,res,next)=>{ // req前端参数 res返回参数 next是否执行下一个中间件

    logger.debug(`[${req.method}]${req.url}`)

    next()

}



export default LoggerModdleware



然后在app.js文件中导入 

app.use(LoggerMiddleware)

06 防盗链

防盗链(Hotlinking)是指在网页或其他网络资源中,通过直接链接到其他网站上的图片、视频或其他媒体文件,从而显示在自己的网页上。这种行为通常会给被链接的网站带来额外的带宽消耗和资源浪费,而且可能侵犯了原始网站的版权。

1 使用referer防止别人盗用我们网站的资源

项目的目录结构:

demo项目的目录

demo/node_modules

demo/app.js

demo/static/node.png

demo/static/index.html

app.js

package-lock.json

package.json


初始化项目:

npm express from 'express'

const app = express()


// 设置防盗链

const whiteList = ['localhost'] // 配置白名单 后期可以配置IP地址

const preventHotLingKing = (req,res,next)=>{

   // 如何获取 referer

   const referer = req.get('referer')

   if(referer){
    
        const {hostname} = new URL(referer)

        if(!whiteList.includes(hostname)){

            res.status(403).send('禁止访问')

        
            retuen false
        }

        next()
    }

   


}

app.use(express.static('static')) // 初始化静态资源

app.listen(3000,()=>{console.log('server started')})


启动项目:

node app.js

访问图片资源:

浏览器:http://localhost:80/node.png   不用加static的前缀


加前缀访问的配置:

app.use('assets',express.static('static'))

浏览器访问 http://localhost:3000/assets/node.png





07 响应头与请求头

1 解决跨域问题,后端设置响应头,允许前端请求

创建中间件

第一个请求头解决跨域的:Access-Control-Allow-Origin

app.use(*,(req,res,next)=>{

    // * 代表所有可访问

    // 第二个参数还可以设置允许访问的ip 'http://localhost:5000' 这是常用的

    res.setHeader('Access-Control-Allow-Origin','*') // * 代表允许所有资源访问

})



2 解决PUT PATCH等请求方式
 

第二个请求头解决请求方式的:Accrss-Control-Allow-Methods:默认只支持post get head delete

app.use(*,(req,res,next)=>{

    res.setHeader('Access-Control-Allow-Origin','http://localhost:5000') 

    // 追加其他请求方式

    res.setHeader('Accrss-Control-Allow-Methods','GET,POST,PUT,DELETE,PATCH')

})



3 解决预检请求CORS报错的问题 

第三个请求 预检请求OPTIONS:

满足如下条件才会发起预检请求:

1 请求头 header:{content-type:application/json} 这是请求头不是响应头 

2 自定义请求头

3 非普通请求 patch put delete

CORS默认只认识(application/x-www-from-urlencoede,multipart/from-data,text/plain)

urlencoede这种请求方式相当于参数是 name=zs&age=12

from-data请求格式相当于 new FormData

text/plain: 存文本

当我们把请求头设置为content-type:application/json CORS就会报错

解决问题:

后端设置支持自定义请求头的响应头

app.use(*,(req,res,next)=>{

    res.setHeader('Access-Control-Allow-Origin','http://localhost:5000') 

    // 追加其他请求方式

    res.setHeader('Access-Control-Allow-Methods','GET,POST,PUT,DELETE,PATCH')

    // 支持自定义响应头

    res.setHeader('Access-Control-Allow-Headers','Content-Type')
 
})


4 后端在接口设定中自定义响应头,前端接收响应头的数据

后端接口模拟数据:

app.get('/info',(req,res)=>{

    res.set('xm',123456) // 设置响应头

    res.setHeader('Access-Control-Expose-Header','xm') // 抛出响应头

    res.join({code:200,type:'get'})

})

前端读取自定义响应头的数据

fetch('http://localhost:3000/info',(res)=>{

    const headers = res.headers

    console.log(headers.get('xm')) // 读取响应头

    return res.join()

}).then(data=>{

    console.log(data)
})


5 SSE响应头: webSocket通信, SSE是后端能事实给前端 前端只能一次向后端请求

适合大屏可视化

后端接口:

app.get('/sse',(req,res)=>{

    res.setHeader('Content-Type','text/event-stream')

    setInterval(()=>{

        res.write('data:+ Date.now()')

    },1000)

})

前端通过EventSource来接

const sse = new EventSource('http://localhost:3000/sse')

默认叫message

sse.addEventListener('message',(e)=>{

    console.log(e.data)

})






  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值