node Express 框架

哈。github的地点已替换,求start
https://github.com/mySoul8012

继承~
Express框架

简朴引见一下

Express事实上Node内置的http模块上构建的一层笼统。理论上一切Express完成的功用都能用Node完成
中心特性;

  1. 设置中心件响应http要求
  2. 定义路由表,实行差别的http要求
  3. 先模板通报参数,来动态的衬着html文件

一些网址

npm的Express https://www.npmjs.com/package…
项目地点 https://github.com/expressjs/…
网址和文档 http://expressjs.com/
翻译的中文文档 http://expressjs.com/zh-cn/

装置Express

运用npm装置,并将其保留进入依靠列表中
因为一堵高不可攀的墙大人的题目,所以呢,被迫运用cnpm,运用来自淘宝的镜像,由淘宝完成镜像的同步
节约一点点珍贵的时刻(^o^)/

全新装置的须要装置淘宝的镜像
https://npm.taobao.org/ 运用cnpm替代npm完成装置

-save 的意义为自动更新依靠文件,依靠文件为package.json

PS C:\Users\mingm\Desktop\test\Express> cnpm install express --save
√ Installed 1 packages
√ Linked 46 latest versions
√ Run 0 scripts
Recently updated (since 2018-07-21): 1 packages (detail see file C:\Users\mingm\Desktop\test\Express\node_modules\.recently_updates.txt)
√ All packages installed (51 packages installed from npm registry, used 3s(network 3s), speed 291.62kB/s, json 47(354.74kB), tarball 535kB)
PS C:\Users\mingm\Desktop\test\Express>

检察依靠pacage.json文件

{
  "dependencies": {
    "express": "^4.16.3"
  }
}

能够看到依靠的是express的4.16.3版本

检察一下目次

PS C:\Users\mingm\Desktop\test\Express> ls


    目次: C:\Users\mingm\Desktop\test\Express


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----        2018/7/28     18:35                node_modules
-a----        2018/7/28     18:35             53 package.json


PS C:\Users\mingm\Desktop\test\Express>

能够检察到有一个node_modules目次,该目次保留的是npm包

一些还须要装置的模块

body-parser 一个node的中心件 用于处置惩罚JSON,等和URL的编码的处置惩罚
https://www.npmjs.com/package…
文档以及项目地点 https://github.com/expressjs/…
cookie-parser 一个担任剖析Cookie的东西能够将传过来的Cookie将其转换为对象
https://www.npmjs.com/package…
multer node.js的中心件 处置惩罚表单数据
项目地点 https://github.com/expressjs/…
npm https://www.npmjs.com/package…
自诉文件 https://github.com/expressjs/…
原版的自述文件 https://github.com/expressjs/…
好啦。一共是一块装置了3个模块
继承运用淘宝源

PS C:\Users\mingm\Desktop\test\Express> cnpm install body-parser --save
√ Installed 1 packages
√ Linked 0 latest versions
√ Run 0 scripts
√ All packages installed (used 248ms(network 242ms), speed 23.48kB/s, json 1(5.68kB), tarball 0B)
PS C:\Users\mingm\Desktop\test\Express> cnpm install cookie-parser --save
√ Installed 1 packages
√ Linked 0 latest versions
√ Run 0 scripts
√ All packages installed (used 264ms(network 258ms), speed 4.99kB/s, json 1(1.29kB), tarball 0B)
PS C:\Users\mingm\Desktop\test\Express> cnpm install multer --save
√ Installed 1 packages
√ Linked 21 latest versions
√ Run 0 scripts
√ All packages installed (22 packages installed from npm registry, used 1s(network 1s), speed 307.56kB/s, json 22(92.57kB), tarball 343.86kB)
PS C:\Users\mingm\Desktop\test\Express>

完成三个模块的装置
检察一下依靠文件

{
  "dependencies": {
    "body-parser": "^1.18.3",
    "cookie-parser": "^1.4.3",
    "express": "^4.16.3",
    "multer": "^1.3.1"
  }
}

依靠四个模块

建立一个框架实例

输出hello world!

// app.js文件
var express = require('express');
var app = express();

app.get('/', (req, res) => {
    res.send('hello world!');
});

var server = app.listen(1938, () => {
    var host = server.address().address;
    var port = server.address().port;

    console.log('%s:%s', host, port);
})
PS C:\Users\mingm\Desktop\index\Express> node app.js
:::1938

此顺序会监听1938上的衔接,当有衔接传入的时刻,运用顺序会以hello world!举行响应,然后将其返回。

路由

路由决议了由谁响应http要求,经由历程提取GET和POST要求的参数,下面继承扩大顺序

PS C:\Users\mingm\Desktop\index\Express> node app.js
{ address: '::', family: 'IPv6', port: 1937 }
var express = require('express');
var app = express();

// 输出hello world
app.get('/', (req, res) => {
    console.log('输出关于主页的GET要求');
    res.send('Hello GET!');
});

// post要求
app.post('/', (req, res) => {
    console.log('主页post要求');
    res.send('Hello POST');
});

// 关于/del_user的页面响应
app.get('/del_user', (req, res) => {
    console.log('这是关于页面 /del_user页面的响应');
    res.send("Hello del_user");
    res.send("你好哈! 这里已将页面举行删除");
});

// /list_user 页面的GET要求
app.get('/list_user', (req, res) => {
    console.log('这里是对 /list_user页面的要求');
    res.send('Hello list_user');
});

// /对页面abcd abcdxcd ab123cd 的要求进去正则
app.get('ab*cd', (req, res) => {
    console.log('举行了正则');
    res.send('hello 正则!');
});

// 启动http服务器
var server = app.listen(1937, () => {
    console.log(server.address());
});

接见 http://127.0.0.1:1937/del_user
返回 Hello del_user
好啦!(^o^)/

剖析静态文件

Express运用了中心件 express.static中心件设置静态文件

事实上是一个http服务器外加一个fs模块完成封装的

目次构造以下

- Express  // 站点文件
    - image // 图片文件夹
        1.gif   // 将要接见的静态资本
    + node_modules  // npm包地点文件夹
    app.js      // 进口文件
    package.json    // 设置文件

代码以下

PS C:\Users\mingm\Desktop\index\Express> node app.js
{ address: '::', family: 'IPv6', port: 1937 }
var express = require('express');
var app = express();

app.use(express.static('./image'));        // 运用中心件 express.static 设置的静态资本文件夹为image

app.get('/', (req, res) => {
    res.send('hello world!');
});

var server = app.listen(1937, () => {
    console.log(server.address());
});

接见 http://127.0.0.1:1937/1.gif
涌现静态资本,(^o^)/

GET要领

res.sendFile()
http://expressjs.com/en/4x/ap…

__dirname 猎取当前实行文件地点目次的完全目次名
res.sendFlie(path [,options] [,fn]) path必需为相对途径,Content-Type 会依据扩大名设置响应的HTTP标头字段,须要注重的是path必需为相对途径

__dirname 猎取当前实行文件地点目次的完全目次名
__filename 猎取当前实行文件带有完全相对途径的文件名
process.cwd() 猎取当前实行node敕令时刻的文件夹的目次名
./ 文件地点目次

req.query 此属性是一个对象,包括路由中每一个查询字符串参数的属性。
304要求 一个前提要求,如果有缓存的数据则举行要求,不然将不会举行要求

<!doctype html>
<html>
<head>
    <title>Hello from</title>
    <meta charset="utf-8">
</head>
<body>
    <form action="/process_get" method="get">
        <label>first_name</label><input type="text" name="first_name"/>
        <label>last_name</label><input type="text" name="last_name"/>
        <input type="submit" value="Submit"/>
    </form>
</body>
</html>
var express = require('express');
var app = express();

app.use(express.static('public'));    // 加载中心件

app.get('/index.html', (req, res) => {    // 挪用中心件指定的静态资本目次 public, 然后挪用回调函数
    res.sendFile( __dirname + '/' + 'index.html');    // 输出html文件的相对途径,采纳的是拼接字符串的体式格局,设置http标头
});

app.get('/process_get', (req, res) => {
    // 输出json花样
    var response = {
        'first_name': req.query.first_name,    // 将http报文中 查询到的first_name的值作为属性值
        'last_name': req.query.last_name    // 同上
    };
    console.log(response); // 输出猎取到的json的值
    res.end(JSON.stringify(response));    // 将猎取到的值转为JSON花样的值,然后举行返回
});

var server = app.listen(1937, () => {
    console.log(server.address());
});

用浏览器检察一下json数据
要求为get 发送的url为 http://127.0.0.1:1937/process_get?first_name=ming&last_name=ming
查询的字符串为
first_name=ming
last_name=ming
统共,要求头为

Host: 127.0.0.1:1937
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Referer: http://127.0.0.1:1937/
Cookie: hibext_instdsigdipv2=1
Connection: keep-alive
Upgrade-Insecure-Requests: 1

主机地点为127.0.0.1:1937
user-Agent为当地的体系的一些信息
剩下的有点看不懂。。╮(╯▽╰)╭
因为设置的是直接返回JSON数据,所以检察一下响应头

{"first_name":"ming","last_name":"ming"}

此为响应载荷
报文为

HTTP/1.1 200 OK
X-Powered-By: Express
Date: Sat, 28 Jul 2018 16:39:08 GMT
Connection: keep-alive
Content-Length: 40

采纳的是http1.1协定,返回的报文为200
同理
DevTol也是云云不在举行论述

下面举行POST要求

须要运用一个中心件 body-parser,其简朴的文档
https://www.npmjs.com/package…

须要运用一个bodyParser.urlencoded 该对象返回剖析urlencoded主体。在返回的body中,将会在req对象上增加一个新的对象,该对象为body。个中的值为字符串和数组,此对象会包括键值对。个中的值能够为字符串和数组(此时设置的extended的值为false),个中的值许可为任何范例的须要设置extended的值为last

var express = require('express');
var app = express();
var bodyParser = require('body-parser');    // 加载Express中心件

// 运用中心件供应的bodyParser.urlencoded对来自于post的url举行剖析,只许可字符串和数字范例的效果
var urlencodeParser = bodyParser.urlencoded({ extended: false });

app.use(express.static('public'));    // 设置静态资本目次为public

// 举行路由婚配
app.get('/index.html', (req, res) => {
    res.sendFile(__dirname + '/' + 'index.html');    // 途径的拼接,拼接的是当前文件的地点目次的相对地点,因为要要求静态资本,自动跳到public文件夹下举行返回
});

// post要求的婚配
app.post('/process_post', urlencodeParser, (req, res) => {    // 先举行回调第一个函数,将post要求,运用中心件举行处置惩罚,处置惩罚完后的值举行返回到req和res即下一个回调函数,数据经由两次回调
    // 输出JSON花样
    var response = {
        'first_name': req.body.first_name,    // 举行键值对的保留
        'last_name': req.body.last_name    
    };
    console.log(response);    // 将接收到的数据举行输出
    res.end(JSON.stringify(response));    // 将键值对保留的对象转化为JSON花样返回给客户端
});

var server = app.listen(1937, () => {    // 开启http服务器
    console.log(server.address());
});
<!doctype html>
<html>
<head>
    <title>Hello from</title>
    <meta charset="utf-8">
</head>
<body>
    <form action="/process_post" method="POST">
        <label>first_name</label><input type="text" name="first_name"/>
        <label>last_name</label><input type="text" name="last_name"/>
        <input type="submit" value="Submit"/>
    </form>
</body>
</html>

ok~
好啦。接见 http://127.0.0.1:1937
趁便翻开浏览器开发者东西举行检察返回的JSON数据

{"first_name":"ming","last_name":"ming"}

♪(^∇^*)圆满~

文件上传

运用post要领完成文件的上传。

from 表单的enctype属性当method属性值为post的时刻,enctype提交的是from给服务器内容的mime范例,即媒体范例,

诠释一下form表单的enctype的三个值

http的post要领,给服务器时,要求主题范例由 Content-Type 指定,一般一个POST要求是经由历程HTML表单发送的,并返回给服务器返回修正的效果,form表单的enctype属性是设置上传的编码的

application/x-www-form-urlencoded 数据被编码成为&举行支解的键值对同时以=作为支解的键值对。非字母和数字的字符会被举行百分比编码 诠释 https://developer.mozilla.org…

multipart/form-data 将会以二进制的体式格局举行上传,上传文件的时刻必需根据这个要领举行提交

text/plain 空格转化为+号,不对其做任何的处置惩罚举行提交

https://developer.mozilla.org…

multer(opts) opts具有一个dest属性,将会通知Multer中心件上传到服务器的位置。

multer(opts)接收链式挪用.array(fieldname[, maxCount]) 支撑一个是不是为文件数组

/*
var express = require('express');
var app = express();    // 建立框架的类
var fs = require('fs');

var bodyParser = require('body-parser');    // 加载中心件
var multer = require('multer');
var storage = multer.diskStorage({ 
    destination: (req, file, cb) => {
        cb(null, './image')    // 文件上传的目次
    },
    filename: (req, file, cb) => {
        var fileFormat = (file.originalname).split(".");    // 先将文件名采纳split根据.举行破裂
        cb(null, file.fieldname + '-' + Date.now() + '.' +  fileFormat[fileFormat.length - 1]);    // 对文件重命名,加上扩大名
    }
});    // 肯定一下上传的设置选项


app.use(express.static('public'));    // 增加静态文件,用于处置惩罚静态文件,框架自带的
app.use(bodyParser.urlencoded({ extended: false }));    // 用于处置惩罚JSON等数据
app.use(multer({storage: storage}).array('image'));

app.get('/index.html', (req, res) => {
    res.sendFile( __dirname + '/' + 'index.html' );    // 关于首页的要求
});

// 该历程中心阅历了对静态文件的(static中心件,urlencoded对url的剖析,只许可字符串和数字的效果,运用了上传的multer的中心件,最后到回调函数)
app.post('/file_upload', (req, res) => {    // 许可上传多个文件,个中文件数组保留在req.files
    console.log(req.files[0]);    // 上传文件的信息
     var des_file = __dirname + "/" + req.files[0].originalname;
   fs.readFile( req.files[0].path, function (err, data) {
        fs.writeFile(des_file, data, function (err) {
         if( err ){
              console.log( err );
         }else{
               response = {
                   message:'File uploaded successfully', 
                   filename:req.files[0].originalname
              };
          }
          console.log( response );
          res.end( JSON.stringify( response ) );
       });
   });
});

var server = app.listen(1937, () => {
    console.log(server.address());
});



*/

var express = require('express');
var app = express();
var fs = require("fs");
 
var bodyParser = require('body-parser');
var multer  = require('multer');
 
app.use(express.static('public'));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(multer({ dest: '/tmp/'}).array('image'));    // 设置暂时上传的地点
 
app.get('/index.htm', function (req, res) {
   res.sendFile( __dirname + "/" + "index.htm" );
})
 
app.post('/file_upload', function (req, res) {
 
   console.log(req.files[0]);  // 上传的文件信息
 
   var fileFormat = (req.files[0].originalname).split(".");
   var fileName = req.files[0].fieldname + '-' + Date.now() + "." + fileFormat[fileFormat.length - 1];
   var des_file = __dirname + "/image/" + fileName;    // 将要上传的地点

    console.log(des_file);
    fs.open( './image/' + fileName, 'a', function(err, fd) {
   if (err) {
       return console.error(err);
   }
  fs.readFile( req.files[0].path, (err, data) => {
            fs.writeFile(des_file, data, (err) => {
            console.log(data);
             if( err ){
                  console.log( err );
             }else{
                   response = {
                       message:'File uploaded successfully', 
                       filename:req.files[0].originalname
                  };
              }
              console.log( response );
              res.end( JSON.stringify( response ) );
               });
           });    
});

          
});
 
var server = app.listen(8081, function () {
 
  var host = server.address().address
  var port = server.address().port
 
  console.log("运用实例,接见地点为 http://%s:%s", host, port)
 
})

思绪,是先将文件以追加的体式格局翻开,然后将经由历程中心件上传的文件写入追加翻开的文件

<html>
<head>
    <title>文件上传表单</title>
</head>
<body>
    <h3>文件上传</h3>
    <form action="/file_upload" method="post" enctype="multipart/form-data">
        <input type="file" name="image" size="50">
        <br>
        <input type="submit" value="上传文件">
    </form>
</body>
</html>

Cookie治理

运用中心件发送Cokie信息。
引入cookie-parser
再引入 util模块,将对象转换为字符串
这个很简朴。过

    原文作者:小小____
    原文地址: https://segmentfault.com/a/1190000015807776
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞