내가 본 거의 모든 Express 앱에는 app.use
미들웨어에 대한 설명이 있지만 실제로 미들웨어가 무엇이며 app.use
명령문이 무엇을하고 있는지에 대한 명확하고 간결한 설명을 찾지 못했습니다 . 표현 문서 자체조차도 약간 모호합니다. 이 개념들을 설명해 주시겠습니까?
내가 본 거의 모든 Express 앱에는 app.use
미들웨어에 대한 설명이 있지만 실제로 미들웨어가 무엇이며 app.use
명령문이 무엇을하고 있는지에 대한 명확하고 간결한 설명을 찾지 못했습니다 . 표현 문서 자체조차도 약간 모호합니다. 이 개념들을 설명해 주시겠습니까?
답변:
나는 새 프로젝트에서 미들웨어 개념을 분리하는 중반 쯤입니다.
미들웨어를 사용하면 처리해야 할 작업 스택을 정의 할 수 있습니다. Express 서버 자체는 미들웨어의 스택입니다.
// express
var app = express();
// middleware
var stack = middleware();
그런 다음 호출하여 미들웨어 스택에 레이어를 추가 할 수 있습니다 .use
// express
app.use(express.static(..));
// middleware
stack.use(function(data, next) {
next();
});
미들웨어 스택의 계층은 함수이며, n 개의 매개 변수 (표현식 req
&에 대한 2 res
)와 next
함수를 갖습니다.
미들웨어는 계층이 계산을 수행하고 매개 변수를 보강 한 다음을 호출 할 것으로 예상합니다 next
.
스택은 처리하지 않으면 아무것도하지 않습니다. Express는 들어오는 HTTP 요청이 서버에서 잡힐 때마다 스택을 처리합니다. 미들웨어를 사용하면 스택을 수동으로 처리합니다.
// express, you need to do nothing
// middleware
stack.handle(someData);
보다 완전한 예 :
var middleware = require("../src/middleware.js");
var stack = middleware(function(data, next) {
data.foo = data.data*2;
next();
}, function(data, next) {
setTimeout(function() {
data.async = true;
next();
}, 100)
}, function(data) {
console.log(data);
});
stack.handle({
"data": 42
})
명시 적으로 용어는 들어오는 모든 HTTP 요청에 대해 명시 적으로 처리하려는 작업 스택을 정의합니다.
연결이 아닌 Express (익스프레스) 측면에서 글로벌 미들웨어 및 라우팅 특정 미들웨어가 있습니다. 즉, 들어오는 모든 HTTP 요청에 미들웨어 스택을 첨부하거나 특정 경로와 상호 작용하는 HTTP 요청에만 미들웨어 스택을 첨부 할 수 있습니다.
익스프레스 및 미들웨어의 고급 예 :
// middleware
var stack = middleware(function(req, res, next) {
users.getAll(function(err, users) {
if (err) next(err);
req.users = users;
next();
});
}, function(req, res, next) {
posts.getAll(function(err, posts) {
if (err) next(err);
req.posts = posts;
next();
})
}, function(req, res, next) {
req.posts.forEach(function(post) {
post.user = req.users[post.userId];
});
res.render("blog/posts", {
"posts": req.posts
});
});
var app = express.createServer();
app.get("/posts", function(req, res) {
stack.handle(req, res);
});
// express
var app = express.createServer();
app.get("/posts", [
function(req, res, next) {
users.getAll(function(err, users) {
if (err) next(err);
req.users = users;
next();
});
}, function(req, res, next) {
posts.getAll(function(err, posts) {
if (err) next(err);
req.posts = posts;
next();
})
}, function(req, res, next) {
req.posts.forEach(function(post) {
post.user = req.users[post.userId];
});
res.render("blog/posts", {
"posts": req.posts
});
}
], function(req, res) {
stack.handle(req, res);
});
app.use()
문법에 약간 혼란스러워 합니다. 미들웨어의 실제 리턴 값은 무엇이며 어떻게 use
합니까?
나는 이전 답변에서 언급되지 않은 것을 추가하기 위해 늦은 답변을 추가합니다.
이제 미들웨어가 클라이언트 요청 과 서버 응답 사이에서 실행되고 있음을 분명히해야합니다 . 가장 일반적인 미들웨어 기능은 오류 관리, 데이터베이스 상호 작용, 정적 파일 또는 기타 리소스에서 정보 얻기입니다. 미들웨어 스택에서 이동하려면 다음 콜백을 호출해야합니다. 미들웨어 기능 끝에서 플로우의 다음 단계로 이동하는 것을 볼 수 있습니다.
app.use
접근 방식을 사용하고 다음 과 같은 흐름을 가질 수 있습니다 .
var express = require('express'),
app = express.createServer(),
port = 1337;
function middleHandler(req, res, next) {
console.log("execute middle ware");
next();
}
app.use(function (req, res, next) {
console.log("first middle ware");
next();
});
app.use(function (req, res, next) {
console.log("second middle ware");
next();
});
app.get('/', middleHandler, function (req, res) {
console.log("end middleware function");
res.send("page render finished");
});
app.listen(port);
console.log('start server');
그러나 다른 접근 방식을 사용하고 각 미들웨어를 함수 인수로 전달할 수도 있습니다. 다음은 Midoware가 클라이언트로 다시 전송 되기 전에 midleware가 Twitter, Github 및 블로그 플로우를 가져 오는 MooTools Nodejs 웹 사이트 의 예입니다response
. 에서 함수가 인수로 전달되는 방식에 유의하십시오 app.get('/', githubEvents, twitter, getLatestBlog, function(req, res){
. 사용 app.get
은 GET 요청에 대해서만 app.use
호출되며 모든 요청에 대해 호출됩니다.
// github, twitter & blog feeds
var githubEvents = require('./middleware/githubEvents')({
org: 'mootools'
});
var twitter = require('./middleware/twitter')();
var blogData = require('./blog/data');
function getLatestBlog(req, res, next){
blogData.get(function(err, blog) {
if (err) next(err);
res.locals.lastBlogPost = blog.posts[0];
next();
});
}
// home
app.get('/', githubEvents, twitter, getLatestBlog, function(req, res){
res.render('index', {
title: 'MooTools',
site: 'mootools',
lastBlogPost: res.locals.lastBlogPost,
tweetFeed: res.locals.twitter
});
});
.get()
방법은 세 가지 유형의 인수, 첫 번째, 마지막 및 중간 인수를 취합니다. 내부적으로는 2보다 많은 인수가 있는지 감지하고 그 중 하나를 미들웨어 함수로 사용하여 왼쪽에서 오른쪽으로 호출합니다.
expressjs 가이드 는 귀하의 질문에 대한 깔끔한 답변을 제공합니다. 가이드의 짧은 스 니펫을 게시하고 있으며 가이드는 매우 좋습니다.
미들웨어 함수는 요청 오브젝트 ( req ), 응답 오브젝트 ( res ) 및 애플리케이션의 요청-응답주기에서 다음 함수에액세스 할 수있는함수입니다. 다음 기능은 Express 라우터의 기능으로, 호출 될 때 현재 미들웨어에 이어 미들웨어를 실행합니다.
미들웨어 기능은 다음 작업을 수행 할 수 있습니다.
현재 미들웨어 함수가 요청-응답주기를 종료하지 않으면 next () 를 호출 하여 제어를 다음 미들웨어 함수로 전달 해야합니다 . 그렇지 않으면 요청이 중단됩니다.
예
다음은 간단한 "Hello World"Express 응용 프로그램의 예입니다. 이 기사의 나머지 부분에서는 두 개의 미들웨어 함수를 정의하고 애플리케이션에 추가합니다. 하나 는 간단한 로그 메시지를 인쇄하는 myLogger 이고 다른 하나 는 HTTP 요청의 시간 소인을 표시하는 requestTime 1 입니다.
var express = require('express')
var app = express()
app.get('/', function (req, res) {
res.send('Hello World!')
})
app.listen(3000)
미들웨어 기능 myLogger
다음은“myLogger”라는 미들웨어 함수의 간단한 예입니다. 이 함수는 앱에 대한 요청이 통과 할 때 "LOGGED"를 인쇄합니다. 미들웨어 함수는 myLogger라는 변수에 지정됩니다.
var myLogger = function (req, res, next) {
console.log('LOGGED')
next()
}
next ()에 대한 호출을 주목하십시오 . 이 함수를 호출하면 앱에서 다음 미들웨어 함수가 호출됩니다. 다음 () 함수는 Node.js를 또는 익스프레스 API의 일부가 아니라 미들웨어 함수에 전달 된 세 번째 인수입니다. 다음 () 함수는 어떤 이름 할 수 있지만 관례 적으로 항상 "다음"이름이 지정됩니다. 혼동을 피하려면 항상이 규칙을 사용하십시오.
미들웨어 함수를로드하려면 미들웨어 함수를 지정하여 app.use ()를 호출 하십시오 . 예를 들어 다음 코드 는 루트 경로 (/) 로의 경로 이전에 myLogger 미들웨어 함수를 로드합니다 .
var express = require('express')
var app = express()
var myLogger = function (req, res, next) {
console.log('LOGGED')
next()
}
app.use(myLogger)
app.get('/', function (req, res) {
res.send('Hello World!')
})
app.listen(3000)
앱이 요청을받을 때마다 "LOGGED"메시지를 터미널에 인쇄합니다.
미들웨어 로딩 순서는 중요합니다. 먼저로드 된 미들웨어 기능도 먼저 실행됩니다.
경우 myLogger이 루트 경로에 대한 경로 후로드, 요청이 결코 도달하지 루트 경로의 경로 핸들러가 요청 - 응답주기를 종료하기 때문에 응용 프로그램은, "LOGGED"를 인쇄하지 않습니다.
미들웨어 함수 myLogger는 단순히 메시지를 인쇄 한 후 next () 함수를 호출하여 요청을 스택의 다음 미들웨어 함수로 전달 합니다.
===== 매우 간단한 설명 =====
미들웨어는 종종 Express.js 프레임 워크에서 사용되며 node.js의 기본 개념입니다. 간단히 말해서, 기본적으로 응용 프로그램의 요청 및 응답 객체에 액세스 할 수있는 기능입니다. 내가 생각하고 싶은 방법은 요청이 응용 프로그램에 의해 처리되기 전에 요청이 통과하는 일련의 '확인 / 사전 화면'입니다. 예를 들어, 미들웨어는 애플리케이션으로 진행하기 전에 요청이 인증되는지 여부를 판별하고 요청이 인증되지 않은 경우 또는 각 요청을 로깅하기 위해 로그인 페이지를 리턴하는 데 적합합니다. 다양한 기능을 가능하게하는 많은 타사 미들웨어를 사용할 수 있습니다.
간단한 미들웨어 예 :
var app = express();
app.use(function(req,res,next)){
console.log("Request URL - "req.url);
next();
}
위의 코드는 들어오는 각 요청에 대해 실행되고 요청 URL을 기록합니다. next () 메소드는 본질적으로 프로그램을 계속할 수있게합니다. next () 함수가 호출되지 않으면 프로그램은 더 이상 진행되지 않으며 미들웨어 실행시 정지됩니다.
몇 가지 미들웨어 문제 :
next()
않지만 return next()
. 차이점은 무엇입니까?
next()
우리가 다음 미들웨어가 호출되는 원하기 때문에, 내가 생각하지 않는다 next()
거나 return next()
, 어떤 차이를 확인해야합니다! 아직도 그것은 코드가 무엇인지에 달려 있습니다 ...
미들웨어는 입력 / 소스 다음에 중간에서 실행되는 기능으로, 최종 출력 일 수 있거나주기가 완료 될 때까지 다음 미들웨어가 사용할 수있는 출력을 생성합니다.
마치 완성, 평가 또는 거부 될 때까지 움직일 때 수정되는 조립 라인을 통과하는 제품과 같습니다.
미들웨어는 일부 값 (예 : 매개 변수 값)이 작동 할 것으로 예상하고 일부 논리에 따라 미들웨어가 다음 미들웨어를 호출하거나 호출하지 않거나 클라이언트에 응답을 보냅니다.
미들웨어 개념을 여전히 파악할 수없는 경우 데코레이터 또는 명령 패턴 체인과 유사한 방식입니다.
일을 단순하게 유지하십시오!
참고 : 답변은 ExpressJS 내장 미드들웨어 사례와 관련이 있지만 미들웨어의 정의 및 사용 사례가 다릅니다.
필자의 관점에서 미들웨어는 유틸리티 또는 도우미 기능으로 작동하지만app.use('path', /* define or use builtin middleware */)
클라이언트의 각 HTTP 요청에 필요한 매우 일반적인 작업을 수행하기위한 코드를 작성하지 않기를 원 함으로써 활성화 및 사용이 완전히 선택적 입니다. 대부분의 응용 프로그램에서 매우 일반적인 쿠키, CSRF 토큰 및 ... 처리와 같은 미들웨어는 스택, 시퀀스 또는 작업 순서에 따라 클라이언트의 각 HTTP 요청에 대해 이러한 모든 작업을 수행하는 데 도움이됩니다. 단일 클라이언트 요청 단위 .
예:
클라이언트 요청을 수락하고 요청에 따라 응답을 제공하는 것은 웹 서버 기술의 특성입니다.
"Hello, world!"만으로 응답을 제공한다고 상상해보십시오. 웹 서버의 루트 URI에 대한 GET HTTP 요청에 대한 텍스트는 매우 간단한 시나리오이며 다른 것이 필요하지 않습니다. 대신 현재 로그인 한 사용자를 확인한 다음 "Hello, Username!" 이 경우 평소보다 더 많은 것이 필요합니다. 모든 클라이언트 요청 메타 데이터를 처리하고 클라이언트 요청에서 가져온 식별 정보를 제공하기 위해 미들웨어가 필요합니다. 그 정보에 따라 현재 사용자를 고유하게 식별 할 수 있으며 그에 대한 응답이 가능합니다 / 그녀는 관련 데이터가 있습니다.
누군가를 돕기를 바랍니다!
매우 기본적인 용어로 이것을 이와 같이 설명하고 싶다면 traversymedia youtube channel express crash course에서 이것을 배웁니다.
좋아, 미들웨어는 경로를 호출 한 후 실행하는 함수입니다.
var logger = function(req, res, next){
console.log('logging...');
next();
}
app.use(logger);
이 로거 기능은 페이지를 새로 고칠 때마다 실행되므로 페이지가 작업 API 호출을 렌더링 한 후 기본적으로 모든 것을 재설정 한 후 필요한 작업을 수행 할 수 있습니다. 미들웨어의 경로 기능 순서가 정말로 중요하거나 작동하지 않기 전에이 미들웨어를 넣으십시오.