新闻详细页实现
const http = require("http"); const fs = require("fs"); const mime = require("./data/mime.json"); const path = require("path"); const cheoor = require("cheerio");//外置模块新模块 -> 处理HTML -> 需要init,然后安装cheerio -S const url = require("url");//内置模块 -> 可以提取路由地址; let newsData = require("./data/data.json"); let server = http.createServer((req,res)=>{ let objPath = url.parse(req.url,true);//可以拿到真正的路由地址 let pathName = objPath.pathname; // console.log(pathName); if(pathName==="/news" || req.url==="/"){ res.setHeader("Content-type","text/html;charset=utf-8"); // res.end("新闻页面"); // 分页相关; // 已知: 当前是那页 页码 : 1,2,3 // 已知: 每页有多少条? // 得到数据 // 接收当前页码 // console.log(objPath.query.p); let p = objPath.query.p || 1;//页码 let perPage = 5;//条 // 1,5 0-5 -> (p-1)*perPage,perPage // 2,5 5,10 -> (p-1)*perPage,perPage // ... splice let nData = JSON.parse( JSON.stringify(newsData)).splice((p-1)*perPage,perPage); // 生成页码 let totalCount = newsData.length; let page = Math.ceil(totalCount/perPage);//页码总数 // 按照数据组装HTML let newHTML = ""; nData.forEach(itme=>{ newHTML += ` <li class="news"> <a href="javascript:;"> <img src="${itme.imgUrl}" alt=""> </a> <div> <h3> <a href="/detail?d=${itme.id}">${itme.title}</a> </h3> <div class="info"> <span class="tips"><span>${itme.from}</span></span> <!-- <span class="line"></span> --> <span class="time">| ${itme.newTime}</span> </div> </div> </li> `; }); // 组装分页 let paginationHtml = `<a href="javascript:;" class="prev">⌜</a>`; for(let i = 1;i<=page;i++){ paginationHtml += `<a href="/news?p=${i}">${i}</a>`; } paginationHtml += `<a href="javascript:;" class="next">⌝</a>`; let indexData = fs.readFileSync("./views/index.html"); let $ = cheoor.load(indexData);//加载处理模板 $(".news-list").html(newHTML);//替换内容 $(".pagination").html(paginationHtml); // res.end(indexData); res.end($.html()) }else if(pathName==="/detail"){ res.setHeader("Content-type","text/html;charset=utf-8"); // 获取后缀内容(?d=) let num = parseInt(objPath.query.d); // 这里的数据是string类型的 // 获取数据内容 let detailMessage = newsData.find(itme=>itme.id===num); // res.end("详细页面") let detailData = fs.readFileSync("./views/detail.html"); let $ = cheoor.load(detailData);//加载处理模板 // $(".title").html(title);//替换内容 $(".text").html(` <h1 class="title">${detailMessage.title}</h1> <div class="article-info"> ${detailMessage.from} 时间:${detailMessage.newTime}</div> <p class="content"> ${detailMessage.title} </p> `) res.end($.html()); }else{ if(pathName!=="/favicon.ico"){ let extName = path.extname(req.url);//获取后缀名 res.setHeader("Content-type",mime[extName]);//配置协议头 let resData = fs.readFileSync("."+req.url); res.end(resData); } } }); server.listen(8787); /* 新闻详细页实现总结: 获取地址栏的id内容 parseInt(objPath.query.d); 获取数据内容 let detailMessage = newsData.find(itme=>itme.id===num); 修改detail.html内容 $(".text").html(``); 加载到页面中 res.end($.html()); */
Koa
它是node的一种框架/模块
准备工作
// 用Koa需要安装 // npm init -y // 初始化一个package.json // npm i koa -S
通过Koa构建服务端
koatext/index.js
const Koa = require("koa");//1.引入koa { // 通过Koa构建服务端: let app = new Koa(); app.use((ctx,next)=>{ ctx.body = "hello world";//输出 }); /* use: ()=>{}; -> 接收回调 两个参数:ctx,next */ app.listen(8989);//指定端口号 }
ctx
koatext/index.js
// ctx讲解: // koa官网: http://koa.bootcss.com/ /* ctx context -> 上下文 原生里面有req和res,Koa就把这两个合并成了ctx; ctx.req -> res.request; ctx.res -> res.response; http.cteateServer((res,req)=>{}); 在ctx里面既有req,也有res; 就是ctx给res和req做了封装 当然Koa也封装了 ctx.request ctx.response等...都可以在官网中查看 req:所有浏览器端到服务端的 res:服务端到浏览器端 */ let app = new Koa(); app.use((ctx,next)=>{ ctx.body = "hello world";//输出 }); /* use: ()=>{}; -> 接收回调 两个参数:ctx,next */ app.listen(8989);//指定端口号
ctx一些用法和别名
// ctx的一些用法和别名 let app = new Koa(); app.use((ctx, next) => { // console.log(ctx.request.query);//{ id: '10' } // 在原生的时候我们还需要url模块去处理,变成对象之后再去拿 // 在koa中直接request.query就可以 ctx.body = { name:"张三", age:20 }; // 当输出是对象的时候,它直接把对象转化为 JSON,也就是有{};会自动去判断 ctx.response.body = "111";//和上面的ctx.body是同样的 { /* 别名 为什么ctx.body就可以直接出现了呢? 本来原生中是需要 res.write();才输出 这里ctx.body === ctx.response.body; 当然也包括很多: ctx.headers === ctx.request.headers; 这里两种写法都是可以的,只是Koa给了别名,方便更好的使用! */ } }); app.listen(8989);//指定端口号
中间件use
koatest/home.js
//中间件的认识 const Koa = require("koa"); { let app = new Koa(); /* { // app.use(); // use -> 中间件,它是一个函数,可以理解为把一些功能加入到app中 } */ /*{ app.use((ctx,next)=>{ // 这个函数其实就是一个中间件 }); }*/ { // 中间件有哪些特点呢? // 1.可以支持多个中间件; 也就是可以加多个到app中 let m1 = function(ctx,next){ console.log("m1..."); }; let m2 = function(ctx,next){ console.log("m2..."); }; app.use(m1);//这步就是让m1和app产生关联 app.use(m2);//也可以use多个 // 其实在底层这边就是 把这些中间件函数放在一个执行队列里面;后面统一执行; // 什么时候执行呢? app.listen(8787);//listen的时候,执行这些队列; // 执行为何没有 执行m2呢? } }
为何不执行m2的讲解 -> next
{ // next讲解; let m1 = function(ctx,next){ console.log("m1..."); next(); // next,提交到下一个use执行;也就是把权力交给了m2 // next(),看需求需不需要使用,不使用省略掉也行~... }; let m2 = function(ctx,next){ console.log("m2..."); ctx.body = "我是m2中间件"; }; app.use(m1); app.use(m2); app.listen(8787); }
{ // next的传参; -> ctx.state let m1 = function(ctx,next){ console.log("m1..."); ctx.state = 10; next(); }; let m2 = function(ctx,next){ console.log("m2..."); console.log(ctx.state);//10 ctx.body = "我是m2中间件"; }; app.use(m1); app.use(m2); app.listen(8787); }
{ // next(); 中间件的执行顺序 -> 洋葱模型 let m1 = function(ctx,next){ console.log("m1...start"); next();// -> m2(); console.log("m1...end") }; let m2 = function(ctx,next){ console.log("m2...start"); ctx.body = "我是m2中间件"; next();// -> m3(); console.log("m2...end"); }; let m3 = function(ctx,next){ console.log("m3...start"); ctx.body = "我是m3中间件"; next();// -> use(); console.log("m3...end"); }; app.use(m1); app.use(m2); app.use(m3); app.use(ctx=>{ ctx.body = "最终输出"; console.log("嘿嘿") }); app.listen(8787); /* 执行结果: m1...start m2...start m3...start 嘿嘿 m3...end m2...end m1...end */ // 所以可以理解为next就是去执行下一个use;当全部执行完毕了之后就返回来执行; }
{ // next(); 中间件的async和await异步 // 当有了异步之后,所有的都需要使用异步 let m1 = async function(ctx,next){ console.log("m1...start"); await next();// -> m2(); console.log("m1...end") }; let m2 = async function(ctx,next){ console.log("m2...start"); ctx.body = "我是m2中间件"; await next();// -> m3(); console.log("m2...end"); }; let m3 = async function(ctx,next){ console.log("m3...start"); ctx.body = "我是m3中间件"; await next();// -> use(); console.log("m3...end"); }; app.use(m1); app.use(m2); app.use(m3); app.use(async ctx=>{ let result = await new Promise(resolve=>{ setTimeout(()=>{ resolve("异步输出") },1000); }); console.log(result); // ctx.body = "最终输出"; ctx.body = result; }); app.listen(8787); }