• express搭建web服务器、路由、get、post请求、multer上传文件、EJS模板引擎的使用


    express官网

    postman工具下载地址

     multer的npm文档地址

    express模板引擎怎么使用  地址:http://www.expressjs.com.cn/guide/using-template-engines.html

    EJS中文文档地址

    首先建立一个server.js

    之后npm init初始化一下

    安装express

    npm install express --save

     在server.js中写入

    var express = require("express");//引入express

    var app = express();//创建express实例

    app.get("/",function(req,res){//定义路由 还有post delete方法 是express定义的
        res.send("服务器响应")
    });

    app.listen(3000);
    console.log("listening to port 3000")

    在运行之前安装一个nodemon插件(全局安装),它可以在服务器代码发生改变时自动启动(方便开发)

    npm install -g nodemon

     运行

    nodemon

    nodemon会自动去找server.js文件并且运行,实际上就是执行node server.js

    如果服务器入口文件叫app.js,那么可以执行nodemon app启动

     之后访问localhost:3000或者http://127.0.0.1:3000就会会看到出现服务器返回的内容:服务器响应!!!好简单的express服务器已经完成了,这比http服务器写路由要简单的多

    上诉的服务器res.send(),返回了个字符串,当然也可以返回json,而且返回json时,不用专门用JSON.stringify()来转换,express框架已经可以自动转换了

    var express = require("express");//引入express
    
    var app = express();//创建express实例
    
    app.get("/",function(req,res){//定义路由 还有post delete方法 是express定义的
        var responseObject = {//也可以是数组 数组也会转化为json
            name:"大伟"
        }
        res.send(responseObject)
    });
    
    app.listen(3000);
    console.log("listening to port 3000")

    也可以把res.send()换成res.json(),前者既可以返回纯文本也可以返回json后者只能返回json

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

    express路由

    var express = require("express");//引入express
    var cors = require('cors');
    var app = express();//创建express实例
    app.use(cors());//为了解决跨域问题
    app.get("/profile/:id/:name",function(req,res){//:后面的id和:name,代表是可变的
        console.log(req.method);//req.method可以拿到前端请求用的是什么方法
        console.dir(req.params);//req.params可以拿到路由上定义的参数值 console.dir是在终端打印出对象的内容
        var responseObject =req.method;
        res.send("you requested to see a profile page"+req.params.id+req.params.name)
    });
    
    app.listen(3000);
    console.log("listening to port 3000")

    上面定义了/profile/:id/:name这样的路由   那么我们在浏览器访问:localhost:3000/profile/xxx/xxx都可以访问到这个页面  而且在服务端还可以拿到客户端输入的这些值

    另外,express的路由 也可以用正则表达式去定义

    var express = require("express");//引入express
    var cors = require('cors');
    var app = express();//创建express实例
    app.use(cors());//为了解决跨域问题
    app.get("/profile/:id/:name",function(req,res){//:后面的id和:name,代表是可变的
        console.log(req.method);//req.method可以拿到前端请求用的是什么方法
        console.dir(req.params);//req.params可以拿到路由上定义的参数值 console.dir是在终端打印出对象的内容
        var responseObject =req.method;
        res.send("you requested to see a profile page"+req.params.id+req.params.name)
    });
    
    app.get("/ab?cd",function(req,res){//?代表前面的b可以出现0次或一次
        res.send("请求成功")
    })
    
    app.listen(3000);
    console.log("listening to port 3000")

    上面用正则定义的路由 可以匹配abcd  或  acd 但是a22cd就匹配不了,这需要对正则有一定了解

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

    express服务器端如何取到 查询字符串(也就是url ?后面的内容)

    下面来新定义一个接口

    var express = require("express");//引入express
    var cors = require('cors');
    var app = express();//创建express实例
    app.use(cors());//为了解决跨域问题
    
    app.get("/",function(req,res){
        console.dir(req.query);
        res.send(req.query);//拿到查询字符串
    });
    
    app.get("/profile/:id/:name",function(req,res){//定义路由
        res.send("you requested to see a profile page"+req.params.id+req.params.name)
    });
    
    app.get("/ab?cd",function(req,res){//?代表前面的b可以出现0次或一次
        res.send("请求成功")
    })
    
    app.listen(3000);
    console.log("listening to port 3000")

    很简单 req.query里面就是查询字符串

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

    下面我们说一下express中的post请求

    在node基础中,我们用了querystring来处理post请求传来的值,在express中我们用body-parser这个插件来处理post传来的值

    首先安装这个插件:

    npm install body-parser --save

    之后在server.js中写一个post请求

    var express = require("express");//引入express
    var cors = require('cors');
    var bodyParser = require('body-parser');//引入body-parser
    var app = express();//创建express实例
    app.use(cors());//为了解决跨域问题
    app.use(bodyParser.urlencoded({extended:false}));//使用body-parser插件
    
    app.post("/",function(req,res){
        console.dir(req.body);//取到post请求传来的数据
        res.send("success");
    })
    app.get("/",function(req,res){
        console.dir(req.query);
        res.send(req.query);//拿到查询字符串
    });
    
    app.get("/profile/:id/:name",function(req,res){//定义路由
        res.send("you requested to see a profile page"+req.params.id+req.params.name)
    });
    
    app.get("/ab?cd",function(req,res){//?代表前面的b可以出现0次或一次
        res.send("请求成功")
    })
    
    app.listen(3000);
    console.log("listening to port 3000")

     我们之前都是用表单来发出post请求的,这次我们用postman来模拟post请求

    postman工具下载地址

     我们进入postman后在地址栏中输入http://localhost:3000  之后请求方法改成POST,之后选择x-www-form-urlencoded(它与form-data的区别是  form-data可以传输文件)

    之后填入key以及value,然后点击send,就可以看到请求的响应了(在body中看)

    除了以上方法外,也可以在一个html页面中,用jquery的ajax方法发送post请求:

        function aa(){
                $.post(
                    'http://127.0.0.1:3000/',
                    {
                        name: 'admin',
                        password: '123'
                    },
                    function(result) {
                        console.log(result)
                        $("#inp").val(result)
                    }
                );
            }

    上诉服务器用bodyparser.urlencoded({extended:false})中间件,来处理post请求发送的form表单数据的,如果我们发送的是json数据该怎么处理呢?:

    var express = require("express");//引入express
    var cors = require('cors');
    var bodyParser = require('body-parser');//引入body-parser 中间件
    var app = express();//创建express实例
    app.use(cors());//为了解决跨域问题
    // app.use(bodyParser.urlencoded({extended:false}));//使用body-parser插件 urlencoded是处理form表单格式的数据的
    app.use(bodyParser.json());//json是处理 json数据的
    
    app.post("/",function(req,res){
        console.dir(req.body);
        res.send(req.body.name);
    })
    app.get("/",function(req,res){
        console.dir(req.query);
        res.send(req.query);//拿到查询字符串
    });
    
    app.get("/profile/:id/:name",function(req,res){//定义路由
        res.send("you requested to see a profile page"+req.params.id+req.params.name)
    });
    
    app.get("/ab?cd",function(req,res){//?代表前面的b可以出现0次或一次
        res.send("请求成功")
    })
    
    app.listen(3000);
    console.log("listening to port 3000")

    将urlencoded换成json就可以处理post传来的json格式的数据了!!!

     那么怎么让不同接口用不同的中间件处理不同的数据呢?

    可以像下面这样:

    var express = require("express");//引入express
    var cors = require('cors');
    var bodyParser = require('body-parser');//引入body-parser 中间件
    var app = express();//创建express实例
    app.use(cors());//为了解决跨域问题
    // app.use(bodyParser.urlencoded({extended:false}));//使用body-parser插件 urlencoded是处理form表单格式的数据的
    // app.use(bodyParser.json());//json是处理 json数据的
    var jsonParser = bodyParser.json();//处理json数据
    var urlencodedParser = bodyParser.urlencoded({extended:false});//处理form表单格式数据
    
    app.post("/",urlencodedParser,function(req,res){//这个接口处理form表单数据
        console.dir(req.body);
        res.send(req.body.name);
    })
    
    app.post("/upload",jsonParser,function(req,res){//这个接口处理json数据
        console.dir(req.body);
        res.send(req.body.name);
    })
    
    app.get("/",function(req,res){
        console.dir(req.query);
        res.send(req.query);//拿到查询字符串
    });
    
    app.get("/profile/:id/:name",function(req,res){//定义路由
        res.send("you requested to see a profile page"+req.params.id+req.params.name)
    });
    
    app.get("/ab?cd",function(req,res){//?代表前面的b可以出现0次或一次
        res.send("请求成功")
    })
    
    app.listen(3000);
    console.log("listening to port 3000")

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

    如何把文件上传到服务器中呢?

    这需要一个库multer

    Multer 是一个 node.js 中间件,用于处理 multipart/form-data 类型的表单数据,它主要用于上传文件。它是写在 busboy之上非常高效。

    注意: Multer 不会处理任何非 multipart/form-data 类型的表单数据。

    先安装这个库

    npm install --save multer

     multer的npm文档地址

    先在服务器同目录下写一个form.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
    </head>
    <body>
        <form action="/upload" method="POST" enctype="multipart/form-data">
            <h2>图片上传</h2>
            <input type="file" name="logo">
            <input type="submit" value="提交">
        </form>
    </body>
    </html>

    在server.js添加:

    var express = require("express");//引入express
    var cors = require('cors');
    var bodyParser = require('body-parser');//引入body-parser 中间件
    var fs = require('fs');//引入文件模块
    var multer = require('multer');//文件上传需要用到
    var upload = multer({dest:'uploads/'});//指定上传的目录 这里指向当前目录下的uploads目录
    var app = express();//创建express实例
    app.use(cors());//为了解决跨域问题
    // app.use(bodyParser.urlencoded({extended:false}));//使用body-parser插件 urlencoded是处理form表单格式的数据的
    // app.use(bodyParser.json());//json是处理 json数据的
    var jsonParser = bodyParser.json();//处理json数据
    var urlencodedParser = bodyParser.urlencoded({extended:false});//处理form表单格式数据
    
    app.get("/form",function(req,res){//文件上传页面
        var form = fs.readFileSync("./form.html",{encoding:'utf8'});
        res.send(form);
    })
    
    app.post("/upload",upload.single('logo'),function(req,res){//上传文件的接口
        res.send({'ret_code':0})
    })
    
    app.post("/",urlencodedParser,function(req,res){//这个接口处理form表单数据
        console.dir(req.body);
        res.send(req.body.name);
    })
    
    app.get("/",function(req,res){
        console.dir(req.query);
        res.send(req.query);//拿到查询字符串
    });
    
    app.get("/profile/:id/:name",function(req,res){//定义路由
        res.send("you requested to see a profile page"+req.params.id+req.params.name)
    });
    
    app.get("/ab?cd",function(req,res){//?代表前面的b可以出现0次或一次
        res.send("请求成功")
    })
    
    app.listen(3000);
    console.log("listening to port 3000")

    以上代码 访问form路由,会呈现出表单页面

    当选择过文件点击提交后会 请求upload接口,此接口会将客户端传过来的文件转换成二进制文件,放在当前目录的uploads文件下;

    以上已经基本完成了文件上传到服务器的功能,但是上传到服务器的文件名称是一大串hash值,分不清楚到底是哪个文件(7e059868d06f6a6d0fafb716c1c4c5cc)

    下面我们需要对文件名称和路径进行进一步设置:

    server.js

    var express = require("express");//引入express
    var cors = require('cors');
    var bodyParser = require('body-parser');//引入body-parser 中间件
    var fs = require('fs');//引入文件模块
    var multer = require('multer');//文件上传需要用到
    var createFolder = function(folder){
        try{
            fs.accessSync(folder);//文件可访问性检查  如果这个文件可访问就没事
        }catch(e){
            fs.mkdirSync(folder);//如果访问不到  就创建个这样的文件
        }
    }
    var uploadFolder = './upload/';
    createFolder(uploadFolder);
    var storage = multer.diskStorage({//磁盘存储引擎
        destination: function (req, file, cb) {//设置存放文件的路径
          cb(null, uploadFolder)
        },
        filename: function (req, file, cb) {//设置文件的名称
          cb(null, file.originalname + '-' + Date.now())
        }
      })
    var upload = multer({ storage: storage });
    var app = express();//创建express实例
    app.use(cors());//为了解决跨域问题
    // app.use(bodyParser.urlencoded({extended:false}));//使用body-parser插件 urlencoded是处理form表单格式的数据的
    // app.use(bodyParser.json());//json是处理 json数据的
    var jsonParser = bodyParser.json();//处理json数据
    var urlencodedParser = bodyParser.urlencoded({extended:false});//处理form表单格式数据
    
    app.get("/form",function(req,res){//文件上传页面
        var form = fs.readFileSync("./form.html",{encoding:'utf8'});
        res.send(form);
    })
    
    app.post("/upload",upload.single('logo'),function(req,res){//上传文件的接口
        console.dir(req.file);//返回上传过来的文件信息
        res.send({'ret_code':0})
    })
    
    app.post("/",urlencodedParser,function(req,res){//这个接口处理form表单数据
        console.dir(req.body);
        res.send(req.body.name);
    })
    
    app.get("/",function(req,res){
        console.dir(req.query);
        res.send(req.query);//拿到查询字符串
    });
    
    app.get("/profile/:id/:name",function(req,res){//定义路由
        res.send("you requested to see a profile page"+req.params.id+req.params.name)
    });
    
    app.get("/ab?cd",function(req,res){//?代表前面的b可以出现0次或一次
        res.send("请求成功")
    })
    
    app.listen(3000);
    console.log("listening to port 3000")

    以上就是上传文件功能

    这里做一个补充,当我们想把一个html页面返回给前台时,不用必须用fs去读取之后再响应到页面,可以直接用express提供的res.sendFile(__dirname+'/form.html');

    app.get("/form",function(req,res){//文件上传页面
        res.sendFile(__dirname+'/form.html')
    })

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

     下面说一下模板引擎,那么模板引擎的使用场景是什么呢?

    就比如上面的form路由会返回一个html页面到前台,但是我们想把res.params.name这个变量传递给html,将这个变量当做html页面的一部分,这该怎么做呢?下面就用到了模板引擎;

    下面来介绍express中的一种模板引擎EJS

    先安装一下:

    npm install ejs --save

    EJS中文文档地址

    可以在百度搜一下 express template 看看express模板引擎怎么使用  地址:http://www.expressjs.com.cn/guide/using-template-engines.html

    下面来使用一下,

    首先更改一下server.js文件中内容

    var express = require("express");//引入express
    var cors = require('cors');
    var bodyParser = require('body-parser');//引入body-parser 中间件
    var fs = require('fs');//引入文件模块
    var multer = require('multer');//文件上传需要用到
    var createFolder = function(folder){
        try{
            fs.accessSync(folder);//文件可访问性检查  如果这个文件可访问就没事
        }catch(e){
            fs.mkdirSync(folder);//如果访问不到  就创建个这样的文件
        }
    }
    var uploadFolder = './upload/';
    createFolder(uploadFolder);
    var storage = multer.diskStorage({//磁盘存储引擎
        destination: function (req, file, cb) {//设置存放文件的路径
          cb(null, uploadFolder)
        },
        filename: function (req, file, cb) {//设置文件的名称
          cb(null, file.originalname + '-' + Date.now())
        }
      })
    var upload = multer({ storage: storage });
    var app = express();//创建express实例
    app.use(cors());//为了解决跨域问题
    app.set('view engine', 'ejs');//使用模板引擎  我们这里使用ejs模板引擎
    // app.use(bodyParser.urlencoded({extended:false}));//使用body-parser插件 urlencoded是处理form表单格式的数据的
    // app.use(bodyParser.json());//json是处理 json数据的
    var jsonParser = bodyParser.json();//处理json数据
    var urlencodedParser = bodyParser.urlencoded({extended:false});//处理form表单格式数据
    
    app.get("/form/:name",function(req,res){//文件上传页面
        var person = req.params.name;
        res.render('form',{person:person})
    })
    
    app.post("/upload",upload.single('logo'),function(req,res){//上传文件的接口
        console.dir(req.file);//返回上传过来的文件信息
        res.send({'ret_code':0})
    })
    
    app.post("/",urlencodedParser,function(req,res){//这个接口处理form表单数据
        console.dir(req.body);
        res.send(req.body.name);
    })
    
    app.get("/",function(req,res){
        console.dir(req.query);
        res.send(req.query);//拿到查询字符串
    });
    
    app.get("/profile/:id/:name",function(req,res){//定义路由
        res.send("you requested to see a profile page"+req.params.id+req.params.name)
    });
    
    app.get("/ab?cd",function(req,res){//?代表前面的b可以出现0次或一次
        res.send("请求成功")
    })
    
    app.listen(3000);
    console.log("listening to port 3000")

    另外,需要在根目录建一个views文件夹,里面建一个form.ejs文件(其实就是html页面,只不过我们可以在里面用ejs的语法)

    根据form/:name接口,我们是把一个person变量传给了模板,那么在form.ejs中怎么取到这个person变量呢?:

    form.ejs:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
    </head>
    <body>
        <h1><%= person %></h1>
        <form action="/upload" method="POST" enctype="multipart/form-data">
            <h2>图片上传</h2>
            <input type="file" name="logo">
            <input type="submit" value="提交">
        </form>
    </body>
    </html>

    上面用<%=  %>将person包裹住,就可以取到了

    然后运行后,在地址栏输入localhost:3000/form/xxxx

    这个xxxx就是person的值,在页面上就可以看到这个值了

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

     上面简单使用了一下ejs模板引擎,下面我们更深入的去使用一下

    我们传递给模板一个对象,里面宝行普通变量,也包含数组,来看看怎么将这些展示出来

    先看路由里面怎样定义

    app.get("/form/:name",function(req,res){//文件上传页面
        var data = {name:"大伟",age:18,arr:["tom","july","bob"]};
        res.render('form',{data:data})
    })

    form.ejs中

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
    </head>
    <body>
        <h1><%= data.name %></h1>
        <h2><%= data.age %></h2>
        <h3><%= data.arr %></h3>
        <ul>
            <% data.arr.forEach(function(item){ %>  
                <li><%= item %></li>
            <% }) %>
        </ul>
        <form action="/upload" method="POST" enctype="multipart/form-data">
            <h2>图片上传</h2>
            <input type="file" name="logo">
            <input type="submit" value="提交">
        </form>
    </body>
    </html>

    以上可以通过forEach把数组循环遍历出来

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

    下面说一下模板共用问题,为什么要模板共用啊,比如说我们有一个网站,上面有一个导航条,每点击一下导航条会切换一个页面,如果每一个导航条在每个页面都写以一遍会比较繁琐,维护起来也比较麻烦。所以下面就说一下ejs的模板共用

    首先我们在views中建立一个文件夹partials,这里面放着一些共用模板,我们在partials文件夹中建立一个header.ejs文件,加入这是一个导航条模板,它会被引入到其它模板中去,

    views/partials/header.ejs:

    <nav>
        <ul>
            <li><a href="javascript:">home</a></li>
            <li><a href="javascript:">about</a></li>
        </ul>
    </nav>

    现在views中已经有一个form.ejs页面了,现在我们再建立一个about.ejs页面,我们要让form.ejs和about.ejs共用header.ejs模板;

    在server.js中 建立对应about页面的路由

    app.get("/about",function(req,res){//文件上传页面
        res.render('about');
    })

    views/about.ejs:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
    </head>
    <body>
        <%- include('partials/header.ejs') -%>
    </body>
    </html>

    同样在form.ejs中也这样引入即可

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
    </head>
    <body>
        <%- include('partials/header.ejs') -%>
        <h1><%= data.name %></h1>
        <h2><%= data.age %></h2>
        <h3><%= data.arr %></h3>
        <ul>
            <% data.arr.forEach(function(item){ %>
                <li><%= item %></li>
            <% }) %>
        </ul>
        <form action="/upload" method="POST" enctype="multipart/form-data">
            <h2>图片上传</h2>
            <input type="file" name="logo">
            <input type="submit" value="提交">
        </form>
    </body>
    </html>

    这样,form.ejs和about.ejs就共用header.ejs模板了!!!

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

  • 相关阅读:
    springmvc最简单的搭建,初学者必看
    搭建服务器需要的那些
    jaxb使用
    Memcached Java Client API详解
    memcached client --ref
    使用Dom4j解析XML
    架构整洁之道
    架构的整理
    VMware虚拟机的三种联网方法及原理
    软件开发进度管理
  • 原文地址:https://www.cnblogs.com/fqh123/p/11562316.html
Copyright © 2020-2023  润新知