Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
Express中間件是在請求和響應之間執行的函數,它可以訪問請求對象(req)、響應對象(res)和應用程序中的下一個中間件函數(通常命名為next)。中間件函數可以執行各種任務,例如修改請求和響應對象、執行身份驗證、記錄請求信息、處理錯誤等。Express中間件是構建強大Web應用程序的關鍵組件之一。以下是關于Express中間件的介紹:
Express提供了一些內置的中間件函數,用于執行常見的任務,例如處理JSON、URL編碼和靜態文件。你可以通過調用app.use()方法來使用這些內置中間件。
你還可以編寫自定義中間件來執行特定的任務。自定義中間件函數采用三個參數:req(請求對象)、res(響應對象)和next(調用下一個中間件函數的函數)。你可以將自定義中間件函數添加到Express應用程序中,以便在請求處理流程中使用它們。
javascript復制代碼app.use((req, res, next)=> {
// 在請求到達時執行的任務
console.log('Middleware executed');
next(); // 調用下一個中間件函數
});
除了內置的和自定義的中間件之外,Express 社區提供了許多第三方中間件,可以用于處理各種任務,如身份驗證、日志記錄、跨域請求等。你可以通過 npm 安裝這些中間件并將它們集成到你的 Express 應用程序中。例如:
bash
復制代碼npm install helmet
然后在應用程序中使用:
javascript復制代碼const helmet=require('helmet');
app.use(helmet());
在 Express 應用程序中,中間件的順序非常重要。中間件的順序決定了它們被執行的順序。通常,你應該先使用那些處理請求的中間件,然后才是處理響應的中間件。例如,使用 express.json() 和 express.urlencoded() 中間件來解析請求體應該放在路由處理程序之前。
Express還允許你定義專門用于處理錯誤的中間件。錯誤處理中間件函數采用四個參數:err(錯誤對象)、req(請求對象)、res(響應對象)和next(調用下一個中間件函數的函數)。你可以在應用程序中定義一個或多個錯誤處理中間件來捕獲并處理在請求處理過程中發生的錯誤。
javascript復制代碼app.use((err, req, res, next)=> {
// 錯誤處理邏輯
console.error(err);
res.status(500).send('Internal Server Error');
});
除了應用級中間件,Express還支持路由級中間件。這些中間件與特定路由相關聯,只在匹配該路由時才會執行。
javascript復制代碼const router=express.Router();
router.use((req, res, next)=> {
// 路由級中間件邏輯
next();
});
router.get('/', (req, res)=> {
res.send('Hello from router');
});
app.use('/api', router);
在Express中,你可以將多個中間件函數鏈接在一起形成中間件鏈。這些中間件函數按照它們添加到鏈中的順序依次執行。你還可以使用app.use()來組合多個中間件函數,使它們在應用程序的所有路由中都得到執行。
javascript復制代碼app.use(middleware1);
app.use('/api', middleware2);
app.use(middleware3);
中間件函數可以是同步的,也可以是異步的。如果中間件函數執行異步操作(如訪問數據庫或調用外部API),則應該在函數體內使用async關鍵字,并且要么在函數體內使用await關鍵字等待異步操作完成,要么返回一個Promise。
javascript復制代碼app.use(async (req, res, next)=> {
try {
await someAsyncOperation();
next();
} catch (err) {
next(err);
}
});
通過充分了解和靈活使用Express中間件的類型、作用、用法和執行順序,開發者可以更好地構建靈活、高效的Node.js應用程序。中間件提供了一個強大的工具集,可以幫助開發者處理各種請求、執行各種任務,并確保應用程序的性能和可維護性。因此,深入學習和掌握Express中間件是構建出色Node.js應用程序的關鍵之一。
比Python,JavaScript才是更適合寫爬蟲的語言。原因有如下三個方面:
一、任務:爬取用戶在Github上的repo信息
通過實例的方式學習爬蟲是最好的方法,先定一個小目標:爬取github repo信息。入口URL如下,我們只需要一直點擊next按鈕就能夠遍歷到用戶的所有repo。
https://github.com/{{username}}?tab=repositories
獲取repo之后,可以做什么?
二、爬蟲雙股劍:axios和jQuery
axios是JavaScript中很常用的異步網絡請求庫,相比jQuery,它更輕量、更專業。既能夠用于瀏覽器端,也可以用于Node。它的語法風格是promise形式的。在本任務中,只需要了解如下用法就足夠了:
axios.get(url).then((resp)=> { 請求成功,處理resp.data中的html數據 }).catch((err)=> { 請求失敗,錯誤處理 })
請求之后需要處理回復結果,處理回復結果的庫當然是用jQuery。實際上,我們有更好的選擇:cheerio。
在node下,使用jQuery,需要使用jsdom庫模擬一個window對象,這種方法效率較低,四個字形容就是:笨重穩妥。
如下代碼使用jQuery解析haha.html文件
fs=require("fs") jquery=require('jquery') jsdom=require('jsdom') //fs.readFileSync()返回結果是一個buffer,相當于byte[] html=fs.readFileSync('haha.html').toString('utf8') dom=new jsdom.JSDOM(html) $=jquery(dom.window) console.log($('h1'))
cheerio只實現了jQuery中的DOM部分,相當于jQuery的一個子集。cheerio的語法和jQuery完全一致,在使用cheerio時,幾乎感覺不到它和jQuery的差異。在解析HTML方面,毫無疑問,cheerio是更好的選擇。如下代碼使用cheerio解析haha.html文件。
cheerio=require('cheerio') html=require('fs').readFileSync("haha.html").toString('utf8') $=cheerio.load(html) console.log($('h1'))
只需20余行,便可實現簡單的github爬蟲,此爬蟲只爬取了一頁repo列表。
var axios=require("axios") var cheerio=require("cheerio") axios.get("https://github.com/weiyinfu?tab=repositories").then(resp=> { var $=cheerio.load(resp.data) var lis=$("#user-repositories-list li") var repos=[] for (var i=0; i < lis.length; i++) { var li=lis.eq(i) var repo={ repoName: li.find("h3").text().trim(), repoUrl: li.find("h3 a").attr("href").trim(), repoDesc: li.find("p").text().trim(), language: li.find("[itemprop=programmingLanguage]").text().trim(), star: li.find(".muted-link.mr-3").eq(0).text().trim(), fork: li.find(".muted-link.mr-3").eq(1).text().trim(), forkedFrom: li.find(".f6.text-gray.mb-1 a").text().trim() } repos.push(repo) } console.log(repos) })
三、更豐富的功能
爬蟲不是目的,而是達成目的的一種手段。獲取數據也不是目的,從數據中提取統計信息并呈現給人才是最終目的。
在github爬蟲的基礎上,我們可以擴展出更加豐富的功能:使用echarts等圖表展示結果。
要想讓更多人使用此爬蟲工具獲取自己的github統計信息,就需要將做成一個網站的形式,通過搜索頁面輸入用戶名,啟動爬蟲立即爬取github信息,然后使用echarts進行統計展示。網站肯定也要用js作為后端,這樣才能和js爬蟲無縫銜接,不然還要考慮跨語言調用。js后端有兩大web框架express和koa,二者API非常相似,并無優劣之分,但express更加流行。
如上設計有一處用戶體驗不佳的地方:當啟動爬蟲爬取github信息時,用戶可能需要等待好幾秒,這個過程不能讓用戶干等著。一種解決思路是:讓用戶看到爬蟲爬取的進度或者爬取過程。可以通過websocket向用戶推送爬取過程信息并在前端進行展示。展示時,使用類似控制臺的界面進行展示。
如何存儲爬取到的數據呢?使用MongoDB或者文件都可以,最好實現兩種存儲方式,讓系統的存儲方式變得可配置。使用MongoDB時,用到js中的連接池框架generic-pool。
整個項目用到的庫包括:
試用地址:
https://weiyinfu.cn/githubstatistic/search.html?
案例地址:https://github.com/weiyinfu/GithubStatistic
原文鏈接:https://zhuanlan.zhihu.com/p/53763115
xpress框架是Node.js基金會的一個項目,官方網址為http://expressjs.com。(中文網站為http://expressjs.com/zh-cn)。它提供了對Node.js原生API比較好的封裝,從而使開發者更容易的使用Node.js,并用來開發強壯的Web、移動應用,以及API的一些其他功能。開發人員還能夠方便的為它開發插件和擴展,從而增加Express的能力。
簡言之,Express 是一個簡潔而靈活的 node.js Web應用框架, 提供了一系列強大特性幫助你創建各種 Web 應用,和豐富的 HTTP 工具。使用 Express 可以快速地搭建一個完整功能的網站。
通過使用Node Express,可以使用更少的代碼來實現功能。至少通過使用Node Express可以實現中間件來響應http請求,可以定義路由表來定義不同請求的響應函數,還可以使用模板引擎來輸出html頁面。其實這也是Express的核心特點。
Express 框架核心特性:
可以設置中間件來響應 HTTP 請求。
定義了路由表用于執行不同的 HTTP 請求動作。
可以通過向模板傳遞參數來動態渲染 HTML 頁面。
好,接下來我們進行Express的安裝,我們通過以下命令就可以安裝 Express 并將其保存到依賴列表中:
npm install express --save
上命令會將 Express 框架安裝在當前目錄的 node_modules 目錄中, node_modules 目錄下會自動創建 express 目錄。以下幾個重要的模塊是需要與 express 框架一起安裝的:
body-parser - node.js 中間件,用于處理 JSON, Raw, Text 和 URL 編碼的數據。
cookie-parser - 這就是一個解析Cookie的工具。通過req.cookies可以取到傳過來的cookie,并把它們轉成對象。
multer - node.js 中間件,用于處理 enctype="multipart/form-data"(設置表單的MIME編碼)的表單數據。
npm install body-parser --save
npm install cookie-parser --save
npm install multer --save
安裝完后,我們可以通過以下npm命令查看 express 使用的版本號:
npm list express
如果小伙伴們進行到了上一步驟,說明我們已經把Express安裝成功了。接下來,我們就可以學習Express和使用它進行一個實例的開發。哈哈,廢話不多說,第一個實例想都不用想,就是用Express框架來輸出Hello World。
以下實例的需求呢就是,我們新建一個demo.js文件,在文件我們需要引入express模塊,并在客戶端發起請求后,響應“Hello World”字符串。
創建demo.js文件,代碼如下所示:
上面代碼寫完之后,我們開始運行,程序運行起來,通過訪問http://localhost:3000/
就可以看到字符串“Hello World”
接下來,我們看看Express是如何處理請求和響應的。
Express 應用使用回調函數的參數: request 和 response 對象來處理請求和響應的數據。
app.get('/', function (req, res) {
// --})
request 和 response 對象的具體介紹:
Request 對象 - request 對象表示 HTTP 請求,包含了請求查詢字符串,參數,內容,HTTP 頭部等屬性。常見屬性有:
1.req.app:當callback為外部文件時,用req.app訪問express的實例
2.req.baseUrl:獲取路由當前安裝的URL路徑
3.req.body / req.cookies:獲得「請求主體」/ Cookies
4.req.fresh / req.stale:判斷請求是否還「新鮮」
5.req.hostname / req.ip:獲取主機名和IP地址
6.req.originalUrl:獲取原始請求URL
7.req.params:獲取路由的parameters
8.req.path:獲取請求路徑
9.req.protocol:獲取協議類型
10.req.query:獲取URL的查詢參數串
11.req.route:獲取當前匹配的路由
12.req.subdomains:獲取子域名
13.req.accepts():檢查可接受的請求的文檔類型
14.req.acceptsCharsets / req.acceptsEncodings / req.acceptsLanguages:返回指定字符集的第一個可接受字符編碼
15.req.get():獲取指定的HTTP請求頭
16.req.is():判斷請求頭Content-Type的MIME類型
Response 對象 - response 對象表示 HTTP 響應,即在接收到請求時向客戶端發送的 HTTP 響應數據。常見屬性有:
1.res.app:同req.app一樣
2.res.append():追加指定HTTP頭
3.res.set()在res.append()后將重置之前設置的頭
4.res.cookie(name,value [,option]):設置Cookie
5.opition: domain / expires / httpOnly / maxAge / path / secure / signed
6.res.clearCookie():清除Cookie
7.res.download():傳送指定路徑的文件
8.res.get():返回指定的HTTP頭
9.res.json():傳送JSON響應
10.res.jsonp():傳送JSONP響應
11.res.location():只設置響應的Location HTTP頭,不設置狀態碼或者close response
12.res.redirect():設置響應的Location HTTP頭,并且設置狀態碼302
13.res.render(view,[locals],callback):渲染一個view,同時向callback傳遞渲染后的字符串,如果在渲染過程中有錯誤發生next(err)將會被自動調用。callback將會被傳入一個可能發生的錯誤以及渲染后的頁面,這樣就不會自動輸出了。
14.res.send():傳送HTTP響應
15.res.sendFile(path [,options] [,fn]):傳送指定路徑的文件 -會自動根據文件extension設定Content-Type
16.res.set():設置HTTP頭,傳入object可以一次設置多個頭
17.res.status():設置HTTP狀態碼
18.res.type():設置Content-Type的MIME類型
今天小編就把Express框架先介紹到這里吧。其實呢,Express框架還有很多核心功能,例如其中的路由、處理靜態文件、處理get請求、post請求等等功能,這寫功能的使用,我們將會在下期在一一介紹,我們下期再見。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。