1.Express的簡單使用
1.簡介
Express 是一個簡潔而靈活的 node.js Web應用框架, 提供了一系列強大特性幫助你創建各種 Web 應用,和豐富的 HTTP 工具。
使用 Express 可以快速地搭建一個完整功能的網站。
Express 框架核心特性:
-
可以設置中間件來響應 HTTP 請求。
-
定義了路由表用於執行不同的 HTTP 請求動作。
-
可以通過向模板傳遞參數來動態渲染 HTML 頁面。
2.安裝
cnpm install --save-dev express
3.運行第一個實例
var express = require('express'); var app = express(); app.get('/', function (req, res) { res.send('Hello World'); }) var server = app.listen(8081, function () { var host = server.address().address var port = server.address().port console.log("應用實例,訪問地址為 http://%s:%s", host, port) })
運行:
C:\Users\Administrator\Desktop\nodejsTest>node ./nodeHttp.js 應用實例,訪問地址為 http://:::8081
瀏覽器訪問:
4.請求和響應
Express 應用使用回調函數的參數: request 和 response 對象來處理請求和響應的數據。
app.get('/', function (req, res) { // -- })
request 和 response 對象的具體介紹:
Request 對象 - request 對象表示 HTTP 請求,包含了請求查詢字符串,參數,內容,HTTP 頭部等屬性。常見屬性有:
- req.app:當callback為外部文件時,用req.app訪問express的實例
- req.baseUrl:獲取路由當前安裝的URL路徑
- req.body / req.cookies:獲得「請求主體」/ Cookies
- req.fresh / req.stale:判斷請求是否還「新鮮」
- req.hostname / req.ip:獲取主機名和IP地址
- req.originalUrl:獲取原始請求URL
- req.params:獲取路由的parameters
- req.path:獲取請求路徑
- req.protocol:獲取協議類型
- req.query:獲取URL的查詢參數串
- req.route:獲取當前匹配的路由
- req.subdomains:獲取子域名
- req.accepts():檢查可接受的請求的文檔類型
- req.acceptsCharsets / req.acceptsEncodings / req.acceptsLanguages:返回指定字符集的第一個可接受字符編碼
- req.get():獲取指定的HTTP請求頭
- req.is():判斷請求頭Content-Type的MIME類型
Response 對象 - response 對象表示 HTTP 響應,即在接收到請求時向客戶端發送的 HTTP 響應數據。常見屬性有:
- res.app:同req.app一樣
- res.append():追加指定HTTP頭
- res.set()在res.append()后將重置之前設置的頭
- res.cookie(name,value [,option]):設置Cookie
- opition: domain / expires / httpOnly / maxAge / path / secure / signed
- res.clearCookie():清除Cookie
- res.download():傳送指定路徑的文件
- res.get():返回指定的HTTP頭
- res.json():傳送JSON響應
- res.jsonp():傳送JSONP響應
- res.location():只設置響應的Location HTTP頭,不設置狀態碼或者close response
- res.redirect():設置響應的Location HTTP頭,並且設置狀態碼302
- res.render(view,[locals],callback):渲染一個view,同時向callback傳遞渲染后的字符串,如果在渲染過程中有錯誤發生next(err)將會被自動調用。callback將會被傳入一個可能發生的錯誤以及渲染后的頁面,這樣就不會自動輸出了。
- res.send():傳送HTTP響應
- res.sendFile(path [,options] [,fn]):傳送指定路徑的文件 -會自動根據文件extension設定Content-Type
- res.set():設置HTTP頭,傳入object可以一次設置多個頭
- res.status():設置HTTP狀態碼
- res.type():設置Content-Type的MIME類型
5.靜態文件
Express 提供了內置的中間件 express.static 來設置靜態文件如:圖片, CSS, JavaScript 等。
你可以使用 express.static 中間件來設置靜態文件路徑。例如,如果你將圖片, CSS, JavaScript 文件放在 public 目錄下,你可以這么寫:
app.use('/public', express.static('public'));
例如:當前目錄/public/test.html 內容如下:
<html> <head></head> <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script> <body> <h1>test</h1> </body> </html>
nodejs源碼如下:
var express = require('express'); var app = express(); app.use('/public', express.static('public')); app.get('/', function (req, res) { res.send('Hello World'); }) var server = app.listen(8081, function () { var host = server.address().address var port = server.address().port console.log("應用實例,訪問地址為 http://%s:%s", host, port) })
運行訪問測試:
6.Cookie 管理
我們可以使用中間件向 Node.js 服務器發送 cookie 信息,以下代碼輸出了客戶端發送的 cookie 信息:
var express = require('express') var cookieParser = require('cookie-parser') var util = require('util'); var app = express() app.use(cookieParser()) app.get('/', function(req, res) { console.log("Cookies: " + util.inspect(req.cookies)); }) app.listen(8081)
缺少模塊需要安裝對應的模塊。
補充:app.use([path,], function [, function...]) 掛載中間件方法到路徑上。如果路徑未指定,那么默認為"/"。
一個路由將匹配任何路徑如果這個路徑以這個路由設置路徑后緊跟着"/"。比如:app.use('/appale', ...)將匹配"/apple","/apple/images","/apple/images/news"等。
中間件方法是順序處理的,所以中間件包含的順序是很重要的。例如:
var express = require('express') var app = express() // this middleware will not allow the request to go beyond it app.use(function(req, res, next) { res.send('Hello World'); }); // this middleware will never reach this route app.use('/', function(req, res) { res.send('Welcome'); }); app.listen(8081)
訪問測試:
參考:https://www.runoob.com/w3cnote/express-4-x-api.html
2.http-proxy-middleware實現代理
參考:https://github.com/chimurai/http-proxy-middleware#proxycontext-config
1.安裝模塊
cnpm install --save-dev http-proxy-middleware
2.簡單的代理
后台springboot代碼:
package cn.qs.controller.test; import java.util.LinkedHashMap; import java.util.Map; import org.apache.commons.collections.MapUtils; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RequestMapping("/test") @RestController public class TestController { @GetMapping("/get") public Map<String, Object> get(@RequestParam Map<String, Object> condition, HttpServletRequest request) { Enumeration<String> headerNames = request.getHeaderNames(); while (headerNames.hasMoreElements()) { String header = (String) headerNames.nextElement(); String value = request.getHeader(header); System.out.println(header + "\t" + value); } if (MapUtils.isEmpty(condition)) { condition = new LinkedHashMap<>(); condition.put("param", null); } return condition; } }
直接訪問后台:
代理代碼:
var express = require('express'); var proxy = require('http-proxy-middleware'); var app = express(); app.use( '/test', proxy({ target: 'http://localhost:8088' }) ); var server = app.listen(80, function () { var host = server.address().address var port = server.address().port console.log("應用實例,訪問地址為 http://%s:%s", host, port) });
啟動:
C:\Users\Administrator\Desktop\nodejsTest>node ./nodeHttp.js [HPM] Proxy created: / -> http://localhost:8088 應用實例,訪問地址為 http://:::80
訪問結果:
后台控制台日志:
cookie JSESSIONID=78CB07C2CD30020D4EB504C1E3659EAD
accept-language zh-CN,zh;q=0.9
accept-encoding gzip, deflate, br
sec-fetch-mode navigate
sec-fetch-site none
accept text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
sec-fetch-user ?1
user-agent Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36
upgrade-insecure-requests 1
cache-control no-cache
pragma no-cache
connection close
host localhost
3.代理進行處理
// include dependencies var express = require('express'); var proxy = require('http-proxy-middleware'); // proxy middleware options var options = { target: 'http://localhost:8088', // target host changeOrigin: true, // needed for virtual hosted sites ws: true, // proxy websockets pathRewrite: { '^/api/server': '', // remove base path '^/api': '/test' // rewrite path }, router: { // when request.headers.host == 'a.com:3000', // override target 'http://localhost:8088' to 'http://b.com:8000' 'a.com:3000': 'http://b.com:8088' } }; // create the proxy (without context) var exampleProxy = proxy(options); // mount `exampleProxy` in web server var app = express(); app.use('/api', exampleProxy); app.listen(3000);
解釋:
(1)changeOrigin為true是改變origin參數到目標鏈接中
(2)ws為true是允許代理websocket請求
(3)pathRewrite是重寫路徑,可以對路徑進行增加、修改、刪除等操作。
(4)router是根據域名以及端口重新定義target。
上面路徑最后的結果如下:(我們可以在hosts配置虛擬域名進行測試)
http://localhost:3000/api/get.html ==== http://localhost:8088/test/get.html
http://localhost:3000/api/server/test/get.html ==== http://localhost:8088/test/get.html
http://a.com:3000/api/get.html ==== http://b.com:8088/test/get.html
http://a.com:3000/api/server/test/get.html ==== http://b.com:8088/test/get.html
測試:
后台控制台代碼:
cookie cookie1=value1
accept-language zh-CN,zh;q=0.9
accept-encoding gzip, deflate
accept text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
user-agent Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36
upgrade-insecure-requests 1
connection close
host b.com:8088