Node.js学习——Express的路由、动态路由、get 传值、引入ejs

一、安装express

1. 局部安装

生成package.json文件。

npm init

或:

npm init -y         // -y表示快速生成

下载并安装express,并写入package.json。

npm install express --save

或简写为:

npm i express -S

2. 全局安装express

npm install express --global

或:

npm i express -g

3. 使用express的脚手架生成器生成项目框架

详情可查看官网:https://www.expressjs.com.cn/starter/generator.html
全局安装express-generator

npm install express-generator -g

使用如下指令在指定目录下新建express项目

express --view=ejs OperateExpressGenerator

此处使用的是ejs模板引擎,OperateExpressGenerator就是新建的express项目目录,
到指定目录下install各个模块

npm  install 

启动项目使用指令

node start

或者

node ./bin/www

二、路由、动态路由、get 传值、请求对象req、响应对象res

const express = require('express')

const app=express()

app.get("/",(req,res)=>{
    res.send("你好 express")
})

app.get('/.*fly$', function(req, res) {    // app.js-路由路径匹配fly结尾的任意路径
    res.send('/.*fly$');
})

app.get("/article",(req,res)=>{
    res.send("新闻页面")
})

app.get("/login",(req,res)=>{
    res.send("登录")
})

app.get("/register",(req,res)=>{  //get:显示数据
    res.send("注册页面")
})
// 请求对象req
// 地址栏输入http://localhost:3000/aa/bb/cc/3?a=1&b=2
app.get('/aa/bb/cc/:id', function (req, res) {
    // 1.req.originalUrl:获取请路由配置的原始url由baseUrl和url组成
    console.log(req.originalUrl); // 返回结果为/aa/bb/cc/3?a=1&b=2

    // 2.req.hostname:获取用户请求的域名 
    console.log(req.hostname);  // localhost

    // 3.req.ip:获取用户请求的ip地址,可以用来设置白名单 
    console.log(req.ip);    // ::1

    // 4.req.method:获取用户请求方法,可以手动实现路由功能 
    console.log(req.method);    // GET

    // 5.req.params:用来获取路由动态参数中的内容 
    console.log(req.params);    // { id: '3' }

    // 6.req.path:获取url请求中的路径,注意不是host,port或query,仅仅是路径,可以手动实现路由功能
    console.log(req.path);  // /aa/bb/cc/3

    // 7.req.protocol:获取客户端请求的协议,一般是http或https
    console.log(req.protocol);  // http

    // 8.req.secure:判断用户是否是https请求,返回boolean值
    console.log(req.secure);    // false

    // 9.req.xhr:用来判断是否是Ajax请求(XMLHttprequest),返回boolean值   
    console.log(req.xhr);   // false

    res.send()
});

// 响应对象res
var goods = {
    "iphonex": {
        "nums": 100,
        "price": 1999.98,
        "color": "red"
    },
    "car": {
        "nums": 100,
        "price": 9999999,
        "color": "black"
    }
}
router.get('/testRes', function (req, res) {
    // 1.res.json():给客户端发送json数据
    res.json({error:0,data:goods}); 

    // 2.res.send():发送数据给客户端,可以是字符串,json对象或buffer
    res.send('success');
    res.send(goods);
    res.send(Buffer.from('Hi,Harrison!')); 

    // 3.res.render():渲染指定模板给客户端
    res.render('index', {
        title: 'Hi,Hou sir!'
    });

    // 4.res.redirect():重定向
    res.redirect('/login');

    // 5.res.status():设置响应header状态码,比如200,301,404,500等
    res.status(200).send('success');

    // 6.res.sendStatus():同样是设置响应header状态码,它等同于send + status两个方法的链式操作
    res.sendStatus(200); // 等效于 res.status(200).send('OK')
    res.sendStatus(403); // 等效于 res.status(403).send('Forbidden')
    res.sendStatus(404); // 等效于 res.status(404).send('Not Found')
    res.sendStatus(500); // 等效于 res.status(500).send('Internal Server Error') 

    // 7.res.set(),res.setHeader:设置响应head信息,如content-type,content-lenght等
    res.setHeader('Content-Type', 'text/html;charset=utf8');
    res.set({
        'Content-Type': 'application/json'
    });

    console.log(res.get('Content-Type'));
    
    res.setHeader('Access-Control-Allow-Origin', '*');
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST');
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type, Authorization');
    res.setHeader("Content-Type", "application/json;charset=utf-8");

    res.end();

    // 8.res.end():结束请求响应循环
    res.end();
});

app.post("/doLogin",(req,res)=>{   //post:增加数据
    console.log("执行登录")
    res.send("执行登录")
})

app.put("/editUser",(req,res)=>{  //put:主要用于修改数据
    console.log("修改用户")
    res.send("修改用户")
})

app.delete("/deleteUser",(req,res)=>{  //delete:主要用于删除数据
    console.log("执行删除")
    res.send("执行删除")
})

app.all('/secret', function(req,res,next){  // all:接收任意的http方法
    res.send('This is all request page!')
})

//路由里面配置多级目录  http://localhost:3000/admin/user/edit
app.get("/admin/user/add",(req,res)=>{
    res.send("admin user add")
})

app.get("/admin/user/edit",(req,res)=>{
    res.send("admin user  edit")
})

//动态路由  配置路由的时候也要注意顺序
app.get("/article/add",(req,res)=>{
    res.send("article add")
})

app.get("/article/:id",(req,res)=>{
    var id=req.params["id"]    //获取动态路由
    res.send("动态路由"+id)
})

app.get('/users/:uid/movies/:mid', function(req, res) {
    res.send(req.params);
    // 访问localhost:3000/users/1/movies/2时得到{'uid':1,'mid':3}
})


//get 传值  http://localhost:3000/product?id=123&cid=123
app.get("/product",(req,res)=>{
    let query = req.query   //获取get传值
    console.log(query)
    res.send("product-"+query.id)
})

app.listen(3000)

注意
1、在使用express获取动态路由时

app.get("/article/:id",(req,res)=>{
    var id=req.params["id"]    //获取动态路由
    res.send("动态路由"+id)
})

id是作为路由类型的占位符,可以替代其他值
2、获取get传值是通过let query = req.query //获取get传值

三、引入ejs

1、安装 cnpm install ejs --save
2、配置 app.set("view engine","ejs")
3、使用 (默认加载模板引擎的文件夹是views)

    res.render("index",{

    })

4、改变加载模板引擎文件夹

app.set('views', __dirname + '/views');

__dirname表示当前文件目录,此处的__dirname + '/views'可以换为其他的文件路径

新建app.js文件

const express = require("express");
const app = express()
//配置模板引擎
app.set("view engine","ejs")

app.get("/",(req,res)=>{
    let title = "你好ejs";
    res.render("index",{
        title:title
    })
})

app.get("/news",(req,res)=>{
    let userinfo={
        username:"张三",
        age:20
    }
    let article="<h3>我是一个h3</h3>"

    let list=["1111","22222","3333333"]

    let newsList=[
        {
            title:"新闻1111",          
        },
        {
            title:"新闻122222",          
        },
        {
            title:"新闻33331",          
        },
        {
            title:"新闻44444",          
        }
    ]

    res.render("news",{
        userinfo:userinfo,
        article:article,
        flag:true,
        score:60,
        list:list,
        newsList:newsList
    })
})

//监听端口  端口号建议写成3000以上
app.listen(3000)

注意
上面的res.render()的第一个参数是需要加载的目录文件
此时新建/views/index.ejs

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h2>我是一个ejs模板引擎</h2>
    <p><%=title%></p>

    <%- include('footer.ejs') %>
</body>
</html>

新建/views/news.ejs

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h2>绑定数据</h2>
    <p><%=userinfo.username%>---<%=userinfo.age%></p>

    <p><%=article%></p>

    <p><%-article%></p>

    <h2>条件判断</h2>

    <%if(flag==true){%>
        <strong>flag=true</strong>
    <%}%>

    <%if(score>=60){%>
        <p>及格</p>
    <%}else{%>
       不及格
    <%}%>

    <h2>循环遍历</h2>

    <ul>
        <%for(let i=0;i<list.length;i++){%>
            <li><%=list[i]%></li>
        <%}%>        
    </ul>
    <br>

    <ul>
        <%for(let i=0;i<newsList.length;i++){%>
            <li><%=newsList[i].title%></li>
        <%}%>        
    </ul>

    <%- include('footer.ejs') %>
</body>
</html>

新建/viewss/footer.ejs

<footer>
    <h1>公共的底部</h1>
</footer>

注意

  • <% “脚本”标签,用于流程控制,无输出;
  • <%_ 删除其前面的空格符;
  • <%= 输出数据到模板,输出的是转义HTML标签;
  • <%- 输出非转义的数据到模板;
  • <%# 注释标签,不执行、不输出内容;
  • <%% 输出字符串 '<%';
  • %> 一般结束标签;
  • -%> 删除紧随其后的换行符;
  • _%> 将结束标签后面的空格符删除。
    例如:
  • <%-%>-后面可以有空格,<%-%>主要就是解析-后面的内容,比如<h3>我是一个h3</h3>include('footer.ejs')
  • <%=%>=后面接的是显示的内容
  • <%%>中可以写JavaScript语句

5、使用ejs模板引擎注册html模板引擎

var ejs = require('ejs'); 
app.engine('html',ejs.__express);
app.set("view engine","html")

此时引入的模板引擎的后缀名改为.html
即将views/index.ejs、views/news.ejs、views/footer.ejs改为views/index.html、views/news.html、views/footer.html、
6、配置静态web目录

app.use(express.static("static"))

此时在目录/static中新建文件bese.css

h1{
    background: red;
}

在views/index.html、views/news.html中引入该css文件就能引入/static中设置的样式

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="/css/base.css">
</head>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容