一、初始化
- 項目初始化
egg-init spider --type=simple
複制代碼
- 安裝依賴
npm i
複制代碼
- 運作測試項目
npm run dev
複制代碼
- 配置模闆引擎
npm i egg-view-ejs
複制代碼
- 找到app/config/plugin.js
exports.ejs = {
enable: true,
package: 'egg-view-ejs'
};
複制代碼
- 找到app/config/config.default.js
config.view = {
mapping: {
'.html': 'ejs'
}
}
複制代碼
- 配置公共的URL位址(config/config.default.js)
config.api = "http://www.phonegap100.com/"
複制代碼
二、抓取新聞接口實作新聞清單與詳情
- 定義新聞清單和新聞詳情路由
router.get('/news', controller.news.index);
router.get('/newscontent', controller.news.content);
複制代碼
- 在service中擷取新聞清單的資料和新聞詳情的資料
async index() {
let list = await this.service.news.getNewsList();
await this.ctx.render('news',{
list
})
}
async content() {
const aid = this.ctx.query.aid;
console.log(aid);
const detail = await this.service.news.getNewsContent(aid);
await this.ctx.render('newscontent',{
detail:detail[0]
})
}
複制代碼
記住:渲染的時候,一定要使用await,因為這是異步渲染,不然可能會報404錯誤。
- 在view視圖層中定義模闆引擎
<h2>新聞清單</h2>
<ul>
<%for (let i = 0; i < list.length; i++) {%>
<li><a href="/newscontent?aid=<%=list[i].aid%>"><%=list[i].title%></a></li>
<%}%>
</ul>
複制代碼
三、Egg.js架構拓展extend
通過Application
- 在app檔案夾下建立檔案夾extend
- 在extend檔案夾下面建立一個application.js,在這個檔案中暴露的函數,均可以通過this.app.xxx來進行調用,但是在application.js内部this就是app。
module.exports = {
foo(param) {
// this 就是 app 對象,在其中可以調用 app 上的其他方法,或通路屬性
console.log(this);
},
};
複制代碼
通過Context
- 在extend檔案夾下建立context.js
- 在context.js中定義想要拓展的函數
module.exports = {
getHost(param) {
// this 就是 ctx 對象,在其中可以調用 ctx 上的其他方法,或通路屬性
return this.request.header.host;
},
};
複制代碼
- 調用拓展的函數
console.log(this.ctx.getHost());
複制代碼
更多其他的拓展方式請通路官網: Egg拓展
通過拓展的形式将時間戳轉換為時間字元串
- 安裝相關子產品并引入
const sd = require('silly-datetime')
module.exports = {
formatTime (param) {
// this 是 helper 對象,在其中可以調用其他 helper 方法
// this.ctx => context 對象
// this.app => application 對象
return sd.format(new Date(param*1000),'YYYY-MM-DD HH:mm')
},
};
複制代碼
- 在模闆引擎中使用
<%=helper.formatTime(list[i].dateline)%>
複制代碼
- 在控制器中使用
通過this.ctx.helper.xxx()
console.log(this.ctx.helper.sendHello());
複制代碼
通過Request
- 在extend檔案夾下面建立request.js
module.exports = {
foo() {
return this.header.host
},
};
複制代碼
- 在控制器中調用
console.log(this.ctx.request.foo());
複制代碼
四、禁止指定IP的通路
Egg調用中間件的時機
比對路由前或比對路由完成時。
中間件的定義與配置、傳值
- 在app檔案夾下建立一個檔案夾middleware檔案夾,并在下面建立一個printdate.js
module.exports = (options,app) => {
console.log(options);
// 傳回一個異步的方法
return async function printDate(ctx,next) {
console.log(new Date());
await next();
}
}
複制代碼
- 在config/config.default.js
config.middleware = ['printdate'];
config.printdate = {
aaa: '123'
}
複制代碼
禁止指定ip通路
- 在app/middleware中建立一個forbidip.js
module.exports = (options,app) => {
// 傳回一個異步的方法
return async function printDate(ctx,next) {
// 要屏蔽的IP
const forbidIp = "127.0.0.1";
// 擷取用戶端的ip
if (ctx.request.ip === forbidIp) {
ctx.status = 403;
ctx.body = "您的IP已經被屏蔽"
} else {
await next();
}
}
}
複制代碼
- 在config/config.default.js中注冊這個中間件
config.middleware = ['printdate','forbidip'];
複制代碼
五、POST送出資料并通過中間件配置CSRF
- 模闆引擎中定義好csrf
<form action="/add?_csrf=<%=csrf%>" method="post">
使用者名:<input type="text" name="username"><br><br>
密碼:<input type="password" name="password"><br><br>
<button type="submit">送出</button>
</form>
複制代碼
- 在app/middleware下建立一個auth.js
module.exports = (option,app) => {
return async function auth(ctx,next) {
// 設定模闆全局變量,之是以要這樣做,是為了讓模闆引擎能夠直接擷取到csrf,而不用每次都傳遞csrf
ctx.state.csrf = ctx.csrf;
await next();
}
}
複制代碼
六、Egg.js中使用Cookie
- 設定cookie的方法
this.ctx.cookies.set('name','zhangsan');
複制代碼
- 擷取cookie的方法
this.ctx.cookies.get('name');
複制代碼
下面介紹下,如何在一個控制器中設定cookie,在另一個控制器中擷取cookie
async index() {
const { ctx } = this;
// 設定cookie
const username = this.ctx.cookies.set('username','zhangsan');
// this.ctx.csrf : 使用者通路這個頁面的時候,生成一個密鑰
await ctx.render('home')
}
複制代碼
async index() {
const username = this.ctx.cookies.get('username')
await this.ctx.render('news', {
username
})
}
複制代碼
- 設定cookie的緩存有效時長
const username = this.ctx.cookies.set('username','zhangsan',{
maxAge: 1000*3600*24
});
複制代碼
- 設定參數
const username = this.ctx.cookies.set('username','zhangsan',{
maxAge: 1000*3600*24,
httpOnly: true,
signed: true, //對cookie進行簽名,防止使用者修改cookie
encrypt: true, // 如果對cookie進行加密,擷取的時候需要解密
});
複制代碼
- 清除cookie
this.ctx.cookies.set('username',null)
複制代碼
Egg.js中使用Seesion
cookie是儲存在用戶端的浏覽器上,而Session則是儲存在伺服器上。當浏覽器通路伺服器并發送第一次請求的時候,服務端會建立一個session對象,生成一個類似與key,value的鍵值對,然後将key(cookie)傳回到浏覽器,浏覽器下次再通路的時候,攜帶key(cookie),找到對應的session(value)。浏覽器首次通路目标伺服器的時候,目标伺服器的響應頭中會包含一個set-cookie字段,浏覽器第二次通路将攜帶cookie進行通路。
- 在控制器中設定session
async setSession() {
this.ctx.session.username = "餘波";
}
複制代碼
- 在控制器中擷取session
async index() {
// 拿到session,并渲染到news頁面中
const username = this.ctx.session.username;
await this.ctx.render('news', {
username
})
}
複制代碼
- 設定session的過期時間(也可以在config中配置session)
this.ctx.session.maxAge = 5000;
複制代碼
- 在config.default.js中配置session
config.session = {
maxAge: 1000*5
}