與 Connect 框架連接
NodeJS 的新手通常會發現它的 API 很難掌握。幸運的是,許多開發人員已經創建了可以更輕鬆地使用 Node.js 的框架。 Connect 就是這樣一個框架。它位於 Node 的 API 之上,在舒適性和控制性之間劃定了界限。
將 Connect 視為中間件堆疊。對於每個請求,Connect 都會透過中間件層進行過濾,每個中間件層都有機會處理 HTTP 請求。當 T.J. Holowaychuk 宣布了 Connect,他說有兩種類型的中間件。第一個是過濾器。
過濾器處理請求,但不回應它(想想伺服器日誌記錄)。
另一種類型是提供者,它會回應請求。您可以根據需要合併任意數量的中間件;請求會遍歷每一層,直到其中一個中間件回應該請求。
基本語法
首先,您需要透過npm安裝Connect套件:
npm install connect
現在建立一個server.js
文件,並加入以下程式碼:
var connect = require("connect");
connect
變數是一個傳回新 Connect 應用程式的函數。因此,我們的下一步是創建該應用程式:
var app = connect();
您不需要為大多數應用程式建立 app
變數。建立應用程式涉及的函數(connect()
和 use()
) 是可連結的:
connect() .use(/* middleware */) .use(/* middleware */) .listen(3000);
use()
函數為應用程式新增了一層中間件,而listen()
函數告訴我們的應用程式開始接受指定連接埠(本例為3000)上的連接。
讓我們從簡單的事情開始:日誌記錄。僅使用日誌記錄中間件的 Connect 應用程式的程式碼相當簡單:
connect() .use(connect.logger()) .listen(3000);
預設情況下,Node 會解析很少的傳入請求。
將程式碼新增到您的檔案中,然後透過執行 node server.js
啟動伺服器。導航到瀏覽器中的任何路徑,並忽略“無法取得...”結果。我們對伺服器發送回瀏覽器的內容不感興趣;我們對伺服器的日誌感興趣。查看終端,您將看到您的請求日誌。請務必查看記錄器文件以取得有關其其他功能和自訂的資訊。
那是一個過濾器;現在讓我們看看一個提供者。最簡單的提供者是靜態提供者;它提供指定資料夾中的靜態檔案。這是它的語法:
.use(connect.static(__dirname + "/public")
你大概可以猜到 Node 的 __dirname
變數的用途:它是目前目錄的路徑。這個中間件靜態地提供目前目錄中 public
資料夾中的任何內容。因此,建立 public/page.html
並新增 <h1>
元素。重新啟動伺服器(node server.js
),然後在瀏覽器中導覽至 localhost:3000/page.html
。您應該在瀏覽器中呈現 page.html
。
現在讓我們快速瀏覽一下 Connect 的其他一些中間件選項。
解析請求體
預設情況下,Node 會解析很少的傳入請求,但如果需要處理更複雜的情況,可以合併多個不同的過濾器來解析請求。有四個過濾器:
-
connect.json()
解析 JSON 請求體(其中content-type
為application/json
)。 -
connect.urlencoded()
解析x-ww-form-urlencoded
請求體。 -
connect.multipart()
解析multipart/form-data
請求體。 -
connect.bodyParser()
是啟用上述所有三個功能的捷徑。
使用任何這些過濾器都可以讓您透過 request.body
存取已解析的正文(我們很快就會討論如何取得 request
物件)。
我認為這些過濾器是如何透過 Connect 細粒度控制的一個很好的例子。您可以使用很少的處理來簡化您的應用程式。
解析 Cookie 和會話
Cookie 和會話是任何 Web 應用程式的重要組成部分,有多個中間件可以幫助管理它們。 connect.cookieParser()
會為您解析 cookie,您可以透過 request.cookies
物件檢索 cookie 及其值。如果您將 connect.session()
過濾器新增到您的應用程式中,這會更有用。此過濾器要求 cookie 解析器已就位。這是一個小例子:
connect() .use(connect.cookieParser()) .use(connect.session({ secret: 'some secret text', cookie: { maxAge: 30000 }})) .use(function(req, res) { var sess = req.session, url = req.url.split("/"); if (url[1] == "name" && url[2]) { sess.name = url[2]; res.end("name saved: " + url[2]); } else if (sess.name) { res.write("session-stored name: " + sess.name); res.end("stored for another: " + (sess.cookie.maxAge / 1000) + " seconds"); } else { res.end("no stored name; go to /name/{name} to save a name"); } }).listen(3000);
您所寫的每個中介軟體都需要將請求傳遞到
next
層或回應請求。
在 cookieParser
之後,我們包含 session
過濾器並傳遞給它兩個選項:
secret
创建一个签名 cookie,用于跟踪会话。cookie.maxAge
定义其生命周期(以毫秒为单位);此代码中的 30000 是 30 秒。
在最后的 use()
调用中,我们传递一个响应请求的函数。我们使用 request
对象中的两个属性:req.session
用于会话数据,req.url
用于请求 URL。
如果应用程序收到对 /name/some_name
的请求,则它将值 some_name
存储在 req.session.name
中。会话中存储的任何内容都可以在会话期间的后续请求中检索。对 /name/other
发出的任何请求都会替换会话变量,对其他 URL 的任何请求都会输出会话变量的值和会话剩余时间。
因此,您可以导航到 localhost:3000/name/your_name
,然后转到 localhost:3000
查看 your_name
。刷新页面几次并观察秒数倒计时。当会话过期时,您将看到默认的“未存储名称”消息。
我提到 cookieParser
过滤器必须位于 session
之前。
包含的顺序对于中间件很重要,因为请求是按顺序从一层传递到另一层的。
由于session
需要解析后的cookie数据,因此请求必须先经过cookieParser
,然后再经过session
。
我可以解释所有其他内置中间件,但在我们编写自己的代码与 Connect 交互之前,我只会再提一些。
- compress:Gzip压缩中间件
- basicAuth:基本http认证
- 目录:列出中间件的目录
- errorHandler:灵活的错误处理程序
编写自己的中间件
您刚刚学习了如何使用 Connect 编写自己的代码。这是基本语法:
.use(function (req, res, next) { })
函数的三个参数很重要;它们提供了通往外部世界的通道。 req
参数当然是请求对象,res
是响应。第三个参数 next
是使函数在中间件堆栈中正常运行的关键。它是一个将请求传递到堆栈中的下一个中间件的函数。请参阅此示例:
connect() .use(function (req, res, next) { if (req.method === 'POST') { res.end("This is a POST request"); } else { next(); } }) .use(function (req, res) { res.end("This is not a POST request (probably a GET request)"); }).listen(3000);
这段代码使用了两个中间件函数。第一个函数检查请求方法以查看是否是 POST 请求。如果是,它就会这样回应。否则,我们调用 next()
并将请求传递给下一个函数,该函数无论如何都会响应。使用 curl
在终端中测试两层:
$ curl http://localhost:3000 This is not a POST request (probably a GET request) $ curl -X POST http://localhost:3000 This is a POST request
如果您不喜欢该终端,请尝试这个有用的 Chrome 插件。
重要的是要记住,您编写的每个中间件函数都需要将请求传递到 next
层或响应请求。如果您的函数分支(通过 if 语句或其他条件),您必须确保每个分支都会传递请求或响应请求。如果您的应用程序在浏览器中挂起,可能是因为您忘记在某个时刻调用 next()
。
现在,那些 request
和 response
参数怎么样?这些与您在使用“原始”节点服务器时收到的请求和响应对象完全相同:
require("http").createServer(function (req, res) { // ... }).listen(3000);
如果您以前没有使用过 Node 的服务器 API,让我向您展示可以用它做什么。
请求对象
request
对象实际上是一个http.IncomingMessage
对象,其重要属性如下::
-
req.method
告诉您使用了哪种 HTTP 方法。 -
req.url
告诉您请求的是哪个 URL。 -
req.headers
是一个包含标头名称和值的对象。 -
req.query
是一个包含查询字符串中任何数据的对象(要解析它,您需要connect.query()
中间件)。 -
req.body
是表单数据的对象(您需要一些正文解析中间件)。 -
req.cookies
是cookie数据的对象(需要cookie解析)。 -
req.session
是会话数据的对象(同样,您需要 cookie 解析和会话中间件)
您可以使用以下代码查看所有这些工作:
connect() .use(connect.query()) // gives us req.query .use(connect.bodyParser()) // gives us req.body .use(connect.cookieParser()) // for session .use(connect.session({ secret: "asdf" })) // gives us req.session .use(function (req, res) { res.write("req.url: " + req.url + "\n\n"); res.write("req.method: " + req.method + "\n\n"); res.write("req.headers: " + JSON.stringify(req.headers) + "\n\n"); res.write("req.query: " + JSON.stringify(req.query) + "\n\n"); res.write("req.body: " + JSON.stringify(req.body) + "\n\n"); res.write("req.cookies: " + JSON.stringify(req.cookies) + "\n\n"); res.write("req.session: " + JSON.stringify(req.session)); res.end(); }).listen(3000);
要查看其中每个值的某些内容,您需要使用查询字符串将一些数据发布到 URL。以下内容应该足够了:
curl -X POST -d "name=YourName" "http://localhost:3000/some/url?some=data"
通过这七个属性,您几乎可以管理收到的任何请求。我不认为经常使用预告片(根据我的经验,我从未见过它们),但是如果您希望在请求中使用预告片,则可以使用 req.trailers
(预告片就像标头一样,但位于正文之后)。
那么,你的回应呢?
响应对象
原始响应对象不提供库(如 Express)为您提供的便利。例如,您无法通过对预制模板的简单渲染调用来响应 - 至少默认情况下不能。响应中的假设很少,因此您需要填写所有小细节。
我们将从状态代码和响应标头开始。您可以使用 writeHead()
方法一次性设置所有这些。以下是 Node 文档中的示例:
var body = 'hello world'; response.writeHead(200, { 'Content-Length': body.length, 'Content-Type': 'text/plain' });
如果需要单独设置header,可以使用setHeader()
方法:
connect() .use(function (req, res) { var accept = req.headers.accept.split(","), body, type; console.log(accept); if (accept.indexOf("application/json") > -1) { type = "application/json"; body = JSON.stringify({ message: "hello" }); } else if (accept.indexOf("text/html") > -1) { type = "text/html"; body = "<h1> Hello! </h1>"; } else { type = "text/plain"; body = "hello!"; } res.statusCode = 200; res.setHeader("Content-Type", type); res.end(body); }).listen(3000);
将此代码添加到文件中,启动服务器并从浏览器请求它。你有 HTML!现在运行:
curl http://localhost:3000
您将收到纯文本。对于 JSON,请尝试以下操作:
curl -H "accept:application/json" http://localhost:3000
全部来自同一个 URL!
如果您需要知道已经设置了哪些标头,请使用 res.getHeader(name)
。您还可以使用 res.removeHeader(name)
删除标头。
当然,没有正文的响应是没有用的。正如您在本教程中所看到的,您可以使用 res.write()
方法将数据块写入正文。它接受字符串或缓冲区对象作为参数。如果是字符串,第二个参数是编码类型(默认为utf8
)。
res.end()
方法关闭主体,但您可以向其传递数据以写入响应流。这在您只需要输出一行的情况下非常有用。
第三方中间件
在普通的旧 Node 和 Connect 中响应较大的 HTML 主体有些困难。这是将第三方中间件加入其中的好地方。您可以在 Connect Github wiki 上找到第三方中间件的列表。例如,我们将使用 connect-jade 包,它允许我们渲染 jade 视图。
首先,安装connect-jade
:
npm install connect-jade
接下来,需要并将其添加为中间件。您需要设置一些默认值:
var connect = require("connect"), connectJade = require("connect-jade"); connect() .use(connectJade({ root: __dirname + "/views", defaults: { title: "MyApp" } })) .use(function (req, res) { res.render("index", { heading: "Welcome to My App" }); }).listen(3000);
将根目录设置为包含视图文件的目录。您还可以设置 defaults
;这些是每个视图中可用的变量,除非我们稍后在调用 render()
时覆盖它们。
此代码中的最后一个函数调用 res.render()
。该方法由 connect-jade
包提供。
它接受的第一个参数是要渲染的视图的名称。
它是视图的路径,无我们在添加中间件时定义的路径,无 jade 文件扩展名。对于这段代码,我们需要一个 views/index.jade
模板来渲染。我们会保持简单:
html head title= title body h1= heading
如果您不熟悉jade,我们会缩进标签名称来创建HTML 结构。等号检索 JavaScript 变量的值。这些变量来自我们设置的 defaults
,加上传递给 res.render()
的(可选)第二个参数对象。
还有许多其他第三方中间件,但它们的工作原理彼此相似。您可以通过 npm 安装它们、需要它们并将它们付诸实践。
模块作为中间件
如果你深入研究 Connect 的工作原理,你会发现每一层实际上都是一个 Node 模块——这是一个非常智能的设计。如果您将 Connect 用于大型应用程序,那么以 Node 模块格式编写代码将是理想的选择。您可能有一个 app.js
文件,如下所示:
// app.js module.exports = function (req, res, next) { res.end("this comes from a module"); };
在你的 server.js
中:
var connect = require("connect"), app = require("./app"); connect() .use(app) .listen(3000);
结论
如果您想要一个适合初学者的库来轻松构建大型 Web 应用程序,那么 Connect 不是您的解决方案。 Connect 旨在成为原始 Node API 之上的一个薄层,让您可以完全控制服务器应用程序。如果你想要更多,我推荐 Express(顺便说一下,是同一个人做的)。除此之外,Connect 是一个出色的、可扩展的 Node Web 应用程序库。
以上是與 Connect 框架連接的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

JavaScript是現代Web開發的基石,它的主要功能包括事件驅動編程、動態內容生成和異步編程。 1)事件驅動編程允許網頁根據用戶操作動態變化。 2)動態內容生成使得頁面內容可以根據條件調整。 3)異步編程確保用戶界面不被阻塞。 JavaScript廣泛應用於網頁交互、單頁面應用和服務器端開發,極大地提升了用戶體驗和跨平台開發的靈活性。

Python和JavaScript開發者的薪資沒有絕對的高低,具體取決於技能和行業需求。 1.Python在數據科學和機器學習領域可能薪資更高。 2.JavaScript在前端和全棧開發中需求大,薪資也可觀。 3.影響因素包括經驗、地理位置、公司規模和特定技能。

實現視差滾動和元素動畫效果的探討本文將探討如何實現類似資生堂官網(https://www.shiseido.co.jp/sb/wonderland/)中�...

JavaScript的最新趨勢包括TypeScript的崛起、現代框架和庫的流行以及WebAssembly的應用。未來前景涵蓋更強大的類型系統、服務器端JavaScript的發展、人工智能和機器學習的擴展以及物聯網和邊緣計算的潛力。

如何在JavaScript中將具有相同ID的數組元素合併到一個對像中?在處理數據時,我們常常會遇到需要將具有相同ID�...

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

探索前端中類似VSCode的面板拖拽調整功能的實現在前端開發中,如何實現類似於VSCode...
