node.js—Express 框架 day1(2019.6.4)

一羽资、nrm

安裝

參考地址:https://www.cnblogs.com/wangmeijian/p/7072053.html

二周循、express框架

安裝

菜鳥教程參考網(wǎng)址:

https://www.runoob.com/nodejs/nodejs-express-framework.html

一凿将、Express框架 Day05

1.課程介紹

  • Express介紹(了解)
  • Express安裝及使用(掌握)
  • Express路由(掌握)
  • response響應(yīng)對(duì)象(掌握)
  • request請(qǐng)求對(duì)象(掌握)
  • 中間件(了解)

2.Express介紹

Express 是一個(gè)基于 Node.js 平臺(tái)的極簡隙赁、靈活的 web 應(yīng)用開發(fā)框架爬骤,它提供一系列強(qiáng)大的特性幢竹,幫助你創(chuàng)建各種 Web 和移動(dòng)設(shè)備應(yīng)用。

Express 框架核心特性:

  • 可以設(shè)置中間件來響應(yīng) HTTP 請(qǐng)求伊佃。
  • 定義了路由表用于執(zhí)行不同的 HTTP 請(qǐng)求動(dòng)作窜司。
    (url = 資源) 映射
  • 可以通過向模板傳遞參數(shù)來動(dòng)態(tài)渲染 HTML 頁面。 模板引擎

3.Express使用

3.1.簡單使用(了解)

1航揉、新建一個(gè)NodeJs項(xiàng)目文件夾
2塞祈、npm init 初始化項(xiàng)目配置文件(package.json 包描述文件)
package.json中
    "scripts": {
        //命令
        "start":"node ./index"
     }
    npm start 執(zhí)行”start”后面的代碼。
3帅涂、安裝express

npm install express --save

4议薪、編寫一個(gè)app.js使用express
//導(dǎo)入express模塊
var express = require("express");
//創(chuàng)建一個(gè)express應(yīng)用
var app = express();

//處理"/"請(qǐng)求
app.get("/",function(req,res){
     //響應(yīng)輸出“hello world”
     res.send("Hello world");
});

//啟動(dòng)服務(wù)器監(jiān)聽3000端口
app.listen(3000,function(){
      console.log("express app 啟動(dòng)成功。媳友。斯议。");
});
5、啟動(dòng)服務(wù)器

node app.js

6醇锚、瀏覽器訪問
image.png

3.2.Express-generator(重點(diǎn))

為了快速的創(chuàng)建express項(xiàng)目哼御,express團(tuán)隊(duì)為使用者提供了項(xiàng)目快速生成工具,express-generator焊唬。

1恋昼、安裝express-generator

npm i express-generator -g //全局安裝

2、新建一個(gè)目錄(或者找一個(gè)空目錄)

F:\webproject (目錄可以新建在任何位置赶促,但最好不要中文路徑)

3液肌、通過命令創(chuàng)建express項(xiàng)目

express -e projecname (express代表在當(dāng)前目錄下面建立express項(xiàng)目 -e代表使用ejs模版引擎)

express webapp (代表在當(dāng)前目錄下面,新建一個(gè)webapp文件夾芳杏,然后在建立express項(xiàng)目)


image.png

項(xiàng)目結(jié)構(gòu):
bin : 執(zhí)行文件矩屁,也是express項(xiàng)目啟動(dòng)文件辟宗。
public:公共的資源,瀏覽器可以直接訪問的資源吝秕。(圖片泊脐,js,css)
views:服務(wù)器端模塊文件烁峭。
routes:路由處理器容客,處理瀏覽器發(fā)出不同url的處理程序。
/login function(){
//登錄處理程序
}
app.js express應(yīng)用的主文件约郁,該文件主要用于整合其他第三方模塊和配置express的系統(tǒng)參數(shù)缩挑。

4、安裝依賴包

通過package.json
"dependencies": {
"body-parser": "~1.15.1",
"cookie-parser": "~1.4.3",
"debug": "~2.2.0",
"ejs": "~2.4.1",
"express": "~4.13.4",
"morgan": "~1.7.0",
"serve-favicon": "~2.3.0"
}
npm i


image.png
5鬓梅、啟動(dòng)express

node app 需要設(shè)置監(jiān)聽端口
npm start
node ./bin/www


image.png
6供置、瀏覽器訪問
image.png

3.3.Express服務(wù)器項(xiàng)目結(jié)構(gòu)說明

bin: 執(zhí)行文件,也是express項(xiàng)目啟動(dòng)文件绽快。

public: 公共的資源(nodejs不做處理)芥丧,瀏覽器可以直接訪問的資源,相當(dāng)于靜態(tài)網(wǎng)頁的根目錄坊罢,訪問時(shí)不需加路徑续担。(圖片,js活孩,css)
http://localhost:3000/test.html
http://localhost:3000/images/img.jpg

views: 服務(wù)器端模塊或模板文件物遇。

routes: 路由處理器,處理瀏覽器發(fā)出不同url的處理程序憾儒。動(dòng)態(tài)網(wǎng)頁的目錄

app.js 主模塊文件询兴,是總路由,分支路由寫在routes目錄下
package.json 包管理航夺,依賴包
    //引入系統(tǒng)和第三方模塊
    var express = require('express');
    var path = require('path');
    var favicon = require('serve-favicon');
    var logger = require('morgan');
    var cookieParser = require('cookie-parser');
    var bodyParser = require('body-parser');

    //引入路由
    var index = require('./routes/index');
    var users = require('./routes/users');
    var vipCenter=require("./routes/vip");

    //實(shí)例化express框架
    var app = express();

    // view engine setup
    //設(shè)置模板的默認(rèn)目錄
    app.set('views', path.join(__dirname, 'views'));
    //設(shè)置ejs為模板引擎
    app.set('view engine', 'ejs');

    // uncomment after placing your favicon in /public
    //app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
    //中間件
    app.use(logger('dev'));
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({ extended: false }));
    app.use(cookieParser());
    //設(shè)置靜態(tài)目錄為public
    app.use(express.static(path.join(__dirname, 'public')));

    //使用分路由
    app.use('/', index);
    app.use('/users', users);
    app.use("/vip",vipCenter);

    // catch 404 and forward to error handler
    //404找不到
    app.use(function(req, res, next) {
      var err = new Error('Not Found');
      err.status = 404;
      next(err);
    });

    // error handler
    //錯(cuò)誤
    app.use(function(err, req, res, next) {
      // set locals, only providing error in development
      res.locals.message = err.message;
      res.locals.error = req.app.get('env') === 'development' ? err : {};

      // render the error page
      res.status(err.status || 500);
      res.render('error');
    });
    //導(dǎo)出模塊
module.exports = app;

4. Express路由(重點(diǎn))

路由是指如何定義應(yīng)用的端點(diǎn)(URIs)以及如何響應(yīng)客戶端的請(qǐng)求蕉朵。

路由是由一個(gè) URI崔涂、HTTP 請(qǐng)求(GET阳掐、POST等)和若干個(gè)句柄(函數(shù))組成,它的結(jié)構(gòu)如下: app.METHOD(path, [callback...], callback)冷蚂, app 是 express 對(duì)象的一個(gè)實(shí)例缭保, METHOD 是一個(gè) HTTP 請(qǐng)求方法, path 是服務(wù)器上的路徑蝙茶, callback 是當(dāng)路由匹配時(shí)要執(zhí)行的函數(shù)艺骂。

4.1. 基礎(chǔ)用法

var express = require('express');

var app = express();

//設(shè)置請(qǐng)求路徑“/”對(duì)應(yīng)的處理器

app.get('/', function(req, res) {

  res.send('hello world');

});

4.2. 路由方法

路由與HTTP 請(qǐng)求方法(GET、POST)相關(guān)聯(lián)隆夯。

為應(yīng)用“/”路徑定義的 GET 和 POST 請(qǐng)求:

// 處理get請(qǐng)求方式钳恕,超鏈接别伏、瀏覽器地址欄直接訪問

app.get('/', function (req, res) {

  res.send('處理get請(qǐng)求');

});

// 處理post請(qǐng)求方式,表單提交

app.post('/', function (req, res) {

  res.send('處理post請(qǐng)求');

});

app.all() 是一個(gè)特殊的路由方法忧额,沒有任何 HTTP 方法與其對(duì)應(yīng)厘肮,它的作用是對(duì)于一個(gè)路徑上的所有請(qǐng)求加載中間件。 all相當(dāng)于既可以處理GET睦番,也可以處理POST类茂。

app.all('/, function (req, res, next) {

  res.send('任意方式的請(qǐng)求');

});

4.3. Router(重點(diǎn)中的重點(diǎn))

express.Router 類可以創(chuàng)建模塊化(獨(dú)立的)、可掛載的路由對(duì)象托嚣。Router 對(duì)象是一個(gè)完整的中間件和路由系統(tǒng)巩检,因此常稱其為一個(gè) “mini-app”。

1示启、新建一個(gè)模塊vip.js (express項(xiàng)目要求我們放到routes)

var express = require('express');

var router = express.Router();

// 定義模塊的主頁的路由

router.get('/', function(req, res) {

  res.send('vip首頁');

});

// 定義模塊“/getScore”路徑的路由

router.get('/getScore', function(req, res) {

  res.send('vip積分');

});

module.exports = router;

2兢哭、app.js 使用

var vip = require('./vip);

...

app.use('/vip', vip);  // 路徑“/vip”使用vip路由模塊,這個(gè)行為就是把“vip”模塊掛載到“/vip”路徑下面夫嗓。

? **訪問**

[<u>http://localhost:3000/vip</u>](http://localhost:3000/vip)/           //vip首頁

[<u>http://localhost:3000/vip</u>](http://localhost:3000/vip)/getScore    //vip積分

5. 響應(yīng)對(duì)象(重點(diǎn))

響應(yīng)對(duì)象(res)的方法向客戶端返回響應(yīng)厦瓢,終結(jié)請(qǐng)求響應(yīng)的循環(huán)。如果在路由函數(shù)中一個(gè)方法也不調(diào)用啤月,來自客戶端的請(qǐng)求會(huì)一直掛起煮仇。

5.1. send方法(重點(diǎn)中的重點(diǎn))

send(data) 可以返回任意類型數(shù)據(jù)。

res.send(new Buffer('whoop'));//流

res.send({ some: 'json' });// json數(shù)據(jù)

res.send('<p>some html</p>');//普通文本

//設(shè)置狀態(tài)碼谎仲,并且返回內(nèi)容

res.status(404).send('Sorry, we cannot find that!');

res.status(500).send({ error: 'something blew up' });

5.2. json方法

json(data) 返回json對(duì)象浙垫,一般針對(duì)ajax應(yīng)用。

res.json(null);

res.json({ user: 'tobi' });

//設(shè)置狀態(tài)碼郑诺,并返回json數(shù)據(jù)

res.status(500).json({ error: 'message' });

5.3. jsonp方法

jsonp(data) 返回json對(duì)象夹姥,一般針對(duì)ajax的跨域訪問。
res.jsonp(null);
res.jsonp({ user: 'tobi' });
//設(shè)置狀態(tài)碼辙诞,并返回json數(shù)據(jù)
res.status(500).jsonp({ error: 'message' });

5.4.render視圖模板

ejs模板的使用

index.ejs 模板
<!DOCTYPE html>
<html>
  <head>
    <title><%= title %></title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
    <ul id="mainNav">
       <li><a href="/">首頁</a></li>
       <li><a href="/news">新聞中心</a></li>
       <li><a href="/vip">vip會(huì)員中心</a></li>
       <li><a href="/users">用戶注冊(cè)</a></li>
    </ul>
    <h1><%= title %></h1>
    <p>Welcome to <%= title %></p>
  </body>
</html>

index.js 路由
var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });  //將視圖和數(shù)據(jù)合并后發(fā)送給客戶端

});

5.5.download下載

//下載當(dāng)前目錄下面的xxx.doc文件辙售,并且重命名為yyy.doc。
router.get('/down', function(req, res, next) {
res.download("./downTest.doc","express使用說明.doc")
});

5.6.redirect重定向

重定向到從指定的URL路徑(瀏覽器地址變?yōu)樵O(shè)置的地址)
router.get('/it', function(req, res, next) {
res.redirect("http://www.baidu.cn");
});

5.7.404報(bào)錯(cuò)頁面制作

image.png

router.get('/err', function(req, res, next) {
//res.status(404).send("出錯(cuò)了:文件沒有找到!");
res.status(404).render("error",{message:"很抱歉飞涂,您查看的寶貝不存在旦部,可能已下架或者被轉(zhuǎn)移。"});
});

error.ejs
<h1><%= message %></h1>
<p><img src="./images/err.png" /></p>
5.8.完整api
1.res.app:同req.app一樣
2.res.append():追加指定HTTP頭
3.res.set()在res.append()后將重置之前設(shè)置的頭

4.res.cookie(name较店,value [士八,option]):設(shè)置Cookie
opition: domain / expires / httpOnly / maxAge / path / secure / signed
5.res.clearCookie():清除Cookie
npm install cookie
var cookie=require("cookie");
res.cookie("username",username); // 設(shè)置cookie
req.cookies.名稱 // 取值
res.clearCookie(‘名稱’); // 清除指定名稱的Cookie
手動(dòng)清除cookie,設(shè)置》高級(jí)》清除瀏覽數(shù)據(jù)
router.get("/checkLogin",function(req,res,next){
var username=req.cookies.username;
if(username) {
res.send(true);
}
else{
res.send(false);
}
});


image.png
  1. res.download():傳送指定路徑的文件

  2. res.get():返回指定的HTTP頭

  3. res.json():傳送JSON響應(yīng)

  4. res.jsonp():傳送JSONP響應(yīng)

  5. res.location():只設(shè)置響應(yīng)的Location HTTP頭梁呈,不設(shè)置狀態(tài)碼或者close response

  6. res.redirect():設(shè)置響應(yīng)的Location HTTP頭婚度,并且設(shè)置狀態(tài)碼302

  7. res.send():傳送HTTP響應(yīng)

  8. res.sendFile(path [,options] [官卡,fn]):傳送指定路徑的文件 -會(huì)自動(dòng)根據(jù)文件extension設(shè)定Content-Type

  9. res.set():設(shè)置HTTP頭蝗茁,傳入object可以一次設(shè)置多個(gè)頭

  10. res.status():設(shè)置HTTP狀態(tài)碼

  11. res.type():設(shè)置Content-Type的MIME類型

6. 請(qǐng)求對(duì)象(重點(diǎn))

req(request)對(duì)象包含了數(shù)一次請(qǐng)求中的所有據(jù)(http頭信息醋虏、請(qǐng)求參數(shù)...)

6.1. 獲取瀏覽器地址欄中的參數(shù)(重點(diǎn)中的重點(diǎn))

語法: req.query.參數(shù)名;

比如:http://localhost:3000/user?name=007

      req.query.name;

**搜索功能**

search.html?keywords=筆記本電腦&catetype=it數(shù)碼

router.get('/search.html', function(req, res, next) {

var keywords=req.query.keywords;

var catetype=req.query.catetype;

res.json({"關(guān)鍵詞":keywords,"類別":catetype});

});

6.2. 獲取表單提交的值(重點(diǎn)中的重點(diǎn))

Post提交 req.body.參數(shù)名

Get提交 req.query.參數(shù)名;

login.htmlpublic靜態(tài)文件

<form action="/loginPost" method="post">

    <p>用戶賬號(hào) <input type="text" name="username" /></p>

    <p>登錄密碼 <input type="password" name="pwd" /></p>

    <p><input type="submit" value="Post登錄" /> </p>

</form>

<hr/>

<form action="/loginGet" method="get">

    <p>用戶賬號(hào) <input type="text" name="username" /></p>

    <p>登錄密碼 <input type="password" name="pwd" /></p>

    <p><input type="submit" value="Get登錄" /> </p>

</form>

路由文件

router.get('/loginGet', function(req, res, next) {

var username=req.query.username;

var pwd=req.query.pwd;

res.json({"賬號(hào)":username,"密碼":pwd});

});

router.post('/loginPost', function(req, res, next) {

var username=req.body.username;

var pwd=req.body.pwd;

res.json({"賬號(hào)":username,"密碼":pwd});

});

6.3. 獲取路由中的參數(shù)parameters

京東的產(chǎn)品地址:<u>https://item.jd.com/5268701.html</u>

/product/9999

router.get("/product/:id",function(req,res){

var productID=req.params.id;

res.send("產(chǎn)品的編號(hào)是:"+productID);

});

parameter [p??r?m?t?] params [p??r?ms]

偽靜態(tài): 看起來是一個(gè)靜態(tài)文件哮翘,但其實(shí)是動(dòng)態(tài)的灰粮。好處可以方便搜索引擎收錄

6.4. 獲取ip地址

router.get('/home', function(req, res, next) {

res.send("<h1>我是首頁homepage!!!</h1><p>你的ip地址是:"+req.hostname+"_"+req.ip+"</p>");

});

6.5. 完整api

  1. req.app:當(dāng)callback為外部文件時(shí),用req.app訪問express的實(shí)例

  2. req.baseUrl:獲取路由當(dāng)前安裝的URL路徑

  3. req.body / req.cookies:獲得「請(qǐng)求主體」/ Cookies

  4. req.fresh / req.stale:判斷請(qǐng)求是否還「新鮮」

  5. req.hostname / req.ip:獲取主機(jī)名和IP地址

  6. req.originalUrl:獲取原始請(qǐng)求URL

  7. req.params:獲取路由的parameters

  8. req.path:獲取請(qǐng)求路徑

  9. req.protocol:獲取協(xié)議類型

  10. req.query:獲取URL的查詢參數(shù)串

  11. req.route:獲取當(dāng)前匹配的路由

  12. req.subdomains:獲取子域名

  13. req.accpets():檢查請(qǐng)求的Accept頭的請(qǐng)求類型

  14. req.acceptsCharsets / req.acceptsEncodings / req.acceptsLanguages

  15. req.get():獲取指定的HTTP請(qǐng)求頭

  16. req.is():判斷請(qǐng)求頭Content-Type的MIME類型

7. 中間件(了解)

Express 是一個(gè)自身功能極簡忍坷,完全是由路由中間件構(gòu)成一個(gè)的 web 開發(fā)框架:從本質(zhì)上來說粘舟,一個(gè) Express 應(yīng)用就是在調(diào)用各種中間件。

image.png

7.1.中間件到底是什么

中間件(Middleware)本質(zhì)就是一個(gè)函數(shù)佩研,它可以訪問請(qǐng)求對(duì)象(request object), 響應(yīng)對(duì)象(response object), 和 web 應(yīng)用中處于請(qǐng)求-響應(yīng)循環(huán)流程中的中間件柑肴,一般被命名為 next 的變量。(next 尾函數(shù)旬薯,執(zhí)行下一個(gè)任務(wù))

中間件的功能包括:
執(zhí)行任何代碼晰骑。
修改請(qǐng)求和響應(yīng)對(duì)象。
終結(jié)請(qǐng)求-響應(yīng)循環(huán)绊序。
調(diào)用堆棧中的下一個(gè)中間件硕舆。

如果當(dāng)前中間件沒有終結(jié)請(qǐng)求-響應(yīng)循環(huán),則必須調(diào)用 next() 方法將控制權(quán)交給下一個(gè)中間件骤公,否則請(qǐng)求就會(huì)掛起抚官。

7.2.應(yīng)用級(jí)中間件

應(yīng)用級(jí)中間件綁定到 app 對(duì)象 使用 app.use() 和 app.METHOD(), 其中阶捆, METHOD 是需要處理的 HTTP 請(qǐng)求的方法凌节,例如 GET, PUT, POST 等等,全部小寫洒试。

//最簡單的中間件

app.js
var express = require('express');
var app = express();
…………………………. ………………………….

/*

  • 中間件:
    1. 中間件是一個(gè)函數(shù)
    1. 中間件可以訪問請(qǐng)求對(duì)象和響應(yīng)對(duì)象
    1. 可以阻止請(qǐng)求繼續(xù)執(zhí)行倍奢,如果不阻止,可以調(diào)用尾函數(shù) next()
  • 尾函數(shù)next:
    1. 在一個(gè)中間件中執(zhí)行尾函數(shù)垒棋,就可以調(diào)用下一個(gè)中間件
    1. 如果不用調(diào)用尾函數(shù)卒煞,就阻止執(zhí)行
    1. 在尾函數(shù)后面的代碼會(huì)執(zhí)行,并且是在尾函數(shù)調(diào)起的下一個(gè)中間件結(jié)束后才執(zhí)行
      */

app.use(function(req,res,next){
console.log('111');
next();
console.log('222');
});

app.use(function(req,res,next){
console.log('333');
next();
console.log('444');
});

…………………………. ………………………….
module.exports = app;

7.3.內(nèi)置中間件

Express中只為我們提供了唯一一個(gè)中間件叼架,其他的中間件需要安裝畔裕。

屬性 描述 類型 缺省值
dotfiles 是否對(duì)外輸出文件名以點(diǎn)(.)開頭的文件〉锏铮可選值為 “allow”柴钻、“deny” 和 “ignore” String “ignore”
etag 是否啟用 etag 生成 Boolean true
extensions 設(shè)置文件擴(kuò)展名備份選項(xiàng) Array []
index 發(fā)送目錄索引文件,設(shè)置為 false 禁用目錄索引垢粮。 Mixed “index.html”
lastModified 設(shè)置 Last-Modified 頭為文件在操作系統(tǒng)上的最后修改日期】糠啵可能值為 true 或 false蜡吧。 Boolean true
maxAge 以毫秒或者其<u>字符串格式</u>設(shè)置 Cache-Control 頭的 max-age 屬性毫蚓。 Number 0
redirect 當(dāng)路徑為目錄時(shí),重定向至 “/”昔善。 Boolean true
setHeaders 設(shè)置 HTTP 頭以提供文件的函數(shù)元潘。 Function

下面的例子使用了 express.static 中間件,其中的 options 對(duì)象經(jīng)過了精心的設(shè)計(jì)君仆。
var options = {
dotfiles: 'ignore',
etag: false,
extensions: ['htm', 'html'],
index: false,
maxAge: '1d',
redirect: false,
setHeaders: function (res, path, stat) {
res.set('x-timestamp', Date.now());
}}

app.use(express.static('public', options));
每個(gè)應(yīng)用可有多個(gè)靜態(tài)目錄翩概。
app.use(express.static('public'));
app.use(express.static('uploads'));
app.use(express.static('files'));

app.use(logger('dev')); //控制臺(tái)日志顯示的中間件
app.use(express.static(path.join(__dirname, 'public'))); //靜態(tài)資源目錄的中間件

7.4.第三方中間件

通過使用第三方中間件從而為 Express 應(yīng)用增加更多功能。
安裝所需功能的 node 模塊返咱,并在應(yīng)用中加載钥庇,可以在應(yīng)用級(jí)加載,也可以在路由級(jí)加載咖摹。

Multer 翻譯文檔https://github.com/expressjs/multer/blob/master/doc/README-zh-cn.md
文件上傳中間件的使用

fileUpload.html 靜態(tài)頁面
<form action="/upload" method="post" enctype="multipart/form-data">
<h2>圖片上傳</h2>
<input type="file" name="imgUpload">
<input type="submit" value="上傳">
</form>

index.js 路由
/*

  • npm i multer --save

前端準(zhǔn)備工作:
1评姨、需要一個(gè)表單,表單里面必須有一個(gè)文件域
2萤晴、必須給form表單指定enctype="multipart/form-data" 屬性吐句。
3、提交按鈕類型為submit店读。

后端:接收請(qǐng)求
1:前端請(qǐng)求表單頁面http://127.0.0.1/upload/
2:渲染模板嗦枢,不需加載額外的數(shù)據(jù)。

教程:
http://blog.csdn.net/CatieCarter/article/details/77841208
https://github.com/expressjs/multer
*/

//引入文件模塊
var fs = require("fs");

//引入上傳中間件模塊
var multer = require('multer');

//初始化上傳目錄,自定義本地保存的路徑
//var upload = multer({ dest: './files/' }); //使用storage時(shí)不需要單獨(dú)制定目錄屯断,storage中有目錄設(shè)置
var uploadFolder='./public/files/'; //放入靜態(tài)資源目錄才能正常顯示

// 通過storage的 filename 屬性定制上傳文件名稱
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, uploadFolder); // 保存的路徑净宵,備注:需要自己創(chuàng)建如果不存在會(huì)報(bào)錯(cuò)
},
filename: function (req, file, cb) {
//將保存文件名設(shè)置為 前綴+時(shí)間戳+文件擴(kuò)展名
var extName=file.originalname.substring(file.originalname.lastIndexOf(".")); //.jpg
cb(null, file.fieldname + '_' + new Date().getTime() + extName);
}
});

// 通過 storage 選項(xiàng)來對(duì) 上傳行為 進(jìn)行定制化
var upload = multer({ storage: storage });

//文件上傳的路由,upload.single("imgUpload")指定單個(gè)文件上傳,上傳框的名稱為imgUpload
router.post('/upload',upload.single("imgUpload"), function(req, res, next) {
var fileInfo = req.file; //multer會(huì)將文件的信息寫到 req.file上
console.log('文件類型:', fileInfo.mimetype);
console.log('原始文件名:', fileInfo.originalname);
console.log('文件大泄伞:', fileInfo.size);
console.log('文件保存路徑:', fileInfo.path);

//渲染圖片顯示的模板,直接獲取文件存放的地址择葡,顯示時(shí)不需要public目錄
var filepath=fileInfo.path.toString().replace("public","");
res.render("imgFileList.ejs",{imgShow: filepath});

//直接顯示出來
res.set({"Content-Type":"text/html"});
res.send("<img src='"+fileInfo.path.toString().replace("public","")+"' />");
});

imgFileList.ejs 圖片顯示模板
<body>
<h1>圖片上傳展示</h1>
<p><img src="<%= imgShow%>" /></p>
</body>

Key Description
fieldname Field name 由表單指定
originalname 用戶計(jì)算機(jī)上的文件的名稱
encoding 文件編碼
mimetype 文件的 MIME 類型
size 文件大小(字節(jié)單位)
destination 保存路徑
filename 保存在 destination 中的文件名
path 已上傳文件的完整路徑
buffer 一個(gè)存放了整個(gè)文件的 Buffer

8.課程總結(jié)

8.1.重點(diǎn)

1.安裝 express
2.express的路由編寫
3.請(qǐng)求對(duì)象
4.響應(yīng)對(duì)象

8.2.難點(diǎn)

1.路由編寫
2.中間件

8.3.如何掌握剃氧?

1.此技能通過使用升級(jí)敏储。
2.將常見的用法截圖保存到文件夾中,時(shí)撑蟀埃回顧已添。

8.4.排錯(cuò)技巧(技巧)

1.console.log()方法。

9.作業(yè)

作業(yè)難度: ☆☆☆
1滥酥、在自己的電腦上安裝exress框架
2更舞、如何獲取GET和POST方式傳值,分別使用什么方法坎吻。
3缆蝉、編寫路由實(shí)現(xiàn)一個(gè)簡易的企業(yè)網(wǎng)站基本結(jié)構(gòu),根據(jù)不同鏈接路徑響應(yīng)不同的內(nèi)容。
首頁 | 新聞中心 | 產(chǎn)品展示 | 客戶留言 | 關(guān)于我們 | 聯(lián)系我們 | 官方商城

10.面試題

1.網(wǎng)絡(luò)服務(wù)器的工作原理

11.擴(kuò)展知識(shí)或課外閱讀推薦(可選)

11.1.擴(kuò)展知識(shí)

使用 express-generator 創(chuàng)建的基本框架中各個(gè)目錄的作用刊头,以及靜態(tài)目錄

【補(bǔ)充】 cookie
由于HTTP是無狀態(tài)協(xié)議黍瞧,無法識(shí)別兩次請(qǐng)求之間的關(guān)系,為了識(shí)別用戶身份使用cookie技術(shù)原杂。cookie技術(shù)是一向由服務(wù)器端設(shè)置數(shù)據(jù)印颤,存儲(chǔ)在客戶端瀏覽器緩存中的一項(xiàng)技術(shù)。
只要服務(wù)器向?yàn)g覽器設(shè)置了cookie穿肄,每一次瀏覽器發(fā)起請(qǐng)求時(shí)年局,都會(huì)自動(dòng)攜帶這些cookie數(shù)據(jù)去訪問服務(wù)器。服務(wù)器可以接收到數(shù)據(jù)并識(shí)別用戶身份咸产。

//設(shè)置新的cookie
res.cookie('名稱','值');

//修改cookie
res.cookie('名稱','新的值');

//刪除cookie
res.clearCookie('名稱');

//獲取查詢使用cookie
req.cookies.名稱;

npm i --save nodemon
nodemon appname

11.2.課外閱讀

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末矢否,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子锐朴,更是在濱河造成了極大的恐慌兴喂,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,270評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件焚志,死亡現(xiàn)場(chǎng)離奇詭異衣迷,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)酱酬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門壶谒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人膳沽,你說我怎么就攤上這事汗菜。” “怎么了挑社?”我有些...
    開封第一講書人閱讀 165,630評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵陨界,是天一觀的道長。 經(jīng)常有香客問我痛阻,道長菌瘪,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,906評(píng)論 1 295
  • 正文 為了忘掉前任阱当,我火速辦了婚禮俏扩,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘弊添。我一直安慰自己录淡,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評(píng)論 6 392
  • 文/花漫 我一把揭開白布油坝。 她就那樣靜靜地躺著嫉戚,像睡著了一般刨裆。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上彼水,一...
    開封第一講書人閱讀 51,718評(píng)論 1 305
  • 那天崔拥,我揣著相機(jī)與錄音极舔,去河邊找鬼凤覆。 笑死,一個(gè)胖子當(dāng)著我的面吹牛拆魏,可吹牛的內(nèi)容都是我干的盯桦。 我是一名探鬼主播,決...
    沈念sama閱讀 40,442評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼渤刃,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼拥峦!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起卖子,我...
    開封第一講書人閱讀 39,345評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤略号,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后洋闽,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體玄柠,經(jīng)...
    沈念sama閱讀 45,802評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評(píng)論 3 337
  • 正文 我和宋清朗相戀三年诫舅,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了羽利。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,117評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡刊懈,死狀恐怖这弧,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情虚汛,我是刑警寧澤匾浪,帶...
    沈念sama閱讀 35,810評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站卷哩,受9級(jí)特大地震影響蛋辈,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜殉疼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評(píng)論 3 331
  • 文/蒙蒙 一梯浪、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧瓢娜,春花似錦挂洛、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春柒巫,著一層夾襖步出監(jiān)牢的瞬間励堡,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評(píng)論 1 272
  • 我被黑心中介騙來泰國打工堡掏, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留应结,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,377評(píng)論 3 373
  • 正文 我出身青樓泉唁,卻偏偏與公主長得像鹅龄,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子亭畜,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容