프레임워크가 없는 Nodej가 있는 정적 콘텐츠 서버

프레임워크가 없는 Nodej가 있는 정적 콘텐츠 서버

Nodejs가 있는 정적 서버

이 튜토리얼에서는 nodej만 사용하여 정적 콘텐츠에 대한 단순 http 서버를 설정하는 몇 가지 단계를 안내합니다. 파일 또는 메모리(캐시)에서 요청된 리소스를 제공하고 리소스가 없을 때 오류 메시지로 응답하는 기본 기능을 추가합니다.

그러나 실제로는 이러한 방식으로 http 서버를 거의 실행하지 않지만, Expressjs와 같은 프레임워크가 후드 아래에서 수행하는 작업을 이해하는 것이 매우 유용할 수 있습니다. 또한 로컬 환경에서 매우 간단한 테스트 툴로도 사용할 수 있습니다.

시스템에 노드J를 설치해야 합니다. 최신 버전(12+)이 더 좋습니다. 권장 환경은 Unix like machine이지만 필요하지 않습니다. 대상 대상은 javascript 초보자 또는 nodej에서 http 서버가 어떻게 작동하는지 궁금해 하는 UI 개발자입니다.

다음 절차를 거치겠습니다.

설치 http 서버, 정적 서버란?

규칙 추가 요청 읽는 방법

리소스 찾기 및 캐싱

가장 간단한 것부터 시작하자.

Http 서버는 들어오는 네트워크 트래픽을 수신하는 네트워크 응용 프로그램입니다. 일부 시스템 리소스를 획득하여 이 작업을 수행하고 있습니다. 특히 전용 포트에서 네트워크를 통해 들어오는 트래픽을 수신하는 프로세스를 메모리에 생성합니다. http 서버와 통신하려면 컴퓨터의 물리적 주소와 응용프로그램이 획득한 포트가 필요합니다. Nodejs는 이를 위해 필요한 모든 기능을 제공합니다. nodesj가 어떻게 하는지 봅시다.

nodej를 사용하여 가장 기본적인 http 서버를 시작하고 실행하는 가장 간단한 방법은 다음과 같습니다.

node -e "require('http').createServer((req, res) => {res.end('hello world')}).listen(3000)"

노드가 설치된 Linux 시스템에서 위의 코드를 실행하면 서버가 시작됩니다.

브라우저 URL 표시줄에 http://localhost:3000을 입력하여 확인할 수 있습니다.

또는 새 터미널 창에 다음을 입력하여 다음을 입력합니다.

> curl http://localhost:3000 // expected response is hello world

이 기본적인 예에서 우리는 건물 돌을 쉽게 볼 수 있다. 우리는 객체를 생성하고 수신 수신을 호출하여 주어진 포트에서 연결을 효과적으로 열고 수신 요청이 HTTP 프로토콜을 준수하기를 기다리고 있습니다.

HTTP GET 요청 헤더를 준수하는 텍스트를 보내는 넷캣으로 테스트할 수 있습니다.

printf "GET / HTTP/1.1\r

\r

" | nc 127.0.0.1 3000 // The expected response is again HTTP/1.1 200 OK Date: Tue, 21 Sep 2021 09:59:13 GMT Connection: keep-alive Keep-Alive: timeout=5 Content-Length: 11 hello world%

넷캣은 응답 헤더를 포함하여 응답에서 수신된 모든 내용을 인쇄하기 때문에 조금 더 풍부합니다. 컬도 할 수 있다. -i 플래그를 사용해 보십시오.

createServer() 및 listen()을 제외한 다른 기본 구성요소는 createServer에 전달된 콜백입니다. 요청 및 응답 개체에 대한 참조가 포함되어 있습니다. 이 두 개체를 사용하여 http 서버와 상호 작용할 수 있습니다.

그러나 이 기사는 네트워킹과 프로토콜에 관한 것이 아니라 nodej만을 사용하여 단순한 정적 콘텐츠 서버를 구축하는 방법에 대한 자습서이며, 어떠한 요청에도 "헬로 월드"로 응답하기 때문에 그리 멀리 가지 못한다. 우리가 더 잘 할 수 있는지 보자.

파일의 응답 서비스

우리의 새로운 http 서버의 기능 면에서 한 단계 더 나아가 보자. 우리는 정적 콘텐츠를 제공할 수 있는 서버를 목표로 하고 있습니다. 여기서 static이라는 단어는 javascript의 "static" 키워드와 유사하다는 의미입니다. 사용자 요청 이전에 이미 알려져 있고 정의된 사항입니다. 웹 서버에서 이미지, 아이콘, CSS 파일 등과 같은 파일을 정적 콘텐츠라고 합니다. 따라서 하드코드된 메시지 대신 파일 내용으로 사용자를 서버화합니다.

module.exports = function staticServer() { const path = './static_content'; const port = 3000; // create server object as in previous example var server = http.createServer(function(req, res){ const filePath = path + 'index.html'; fs.readFile(absPath, function(err, data) { res.end(data); }); }); server.listen(port, function() { console.log("server listening on port: " + port)); }); return server; };

또한 다음을 포함하는 디렉토리 및 ./static_content/index.complete.

Hello, this is very simple

위의 코드에서 우리는 정적 콘텐츠가 있는 경로를 정의한다. 이 경우 index.html 파일이다. 우리는 파일을 읽고 클라이언트의 요청에 대한 응답으로 데이터를 사용자에게 다시 보낸다.

response.end()는 일부 기본 헤더를 사용하여 위의 내용을 실행합니다.

요청된 리소스 찾기 및 서비스

사용자 요청에 따라 콘텐츠를 제공하는 퀘스트의 다음 단계는 사용자가 요청한 리소스를 찾는 것입니다. 서버는 해당 파일을 검색하여 존재하는 경우 파일의 내용을 클라이언트에 제공합니다.

module.exports = function staticServer() { const path = './static_content'; const port = 3000; // create server object as in previous example var server = http.createServer(function(req, res){ // get the resource from request const filePath = path + req.url; fs.readFile(absPath, function(err, data) { res.end(fileContents); }); }); server.listen(port, function() { console.log("server listening on port: " + port)); }); return server; };

const filePath = path + req.url은 요청된 리소스와 실제 리소스 간의 매핑이 작동하는 방식을 보여줍니다. 경로는 nodejs 앱이 실행 중인 위치에 대한 상대 경로이며 req.url은 리소스 사용자가 원하는 것을 식별하는 URI의 마지막 비트입니다.

http://www.example.com/**resource**

캐싱

작은 추가 하나 합시다. 캐쉬. 디스크에서 파일을 서버할 때는 매우 빠르기 때문에 큰 문제가 되지 않습니다. 그러나 파일이 시간이 더 많이 드는 리소스에서 가져온다면 나중에 요청하기 위해 파일 내용을 보존해야 합니다. 다음은 구현 가능한 매우 간단한 예입니다.

module.exports = function staticServer() { const path = './static_content'; const port = 3000; const cache = {} // create server object as in previous example var server = http.createServer(function(req, res){ // get the resource from request const filePath = path + req.url; if (cache[filePath]) { sendFile(res, filePath, cache[filePath]); } else { fs.readFile(filePath, function(err, data) { res.end(fileContents); }); } }); server.listen(port, function() { console.log("server listening on port: " + port)); }); return server; };

기본 오류 처리 및 마무리

이 마지막 절에서는 간단한 오류 처리를 추가합니다. 사용자가 지정된 정적 콘텐츠 위치에서 찾을 수 없는 리소스를 지정하거나 리소스를 읽을 수 없는 경우 사용자에게 오류를 알려야 합니다. 일반적인 방법은 응답 헤더에 코드 404로 응답을 반환하는 것입니다. 콘텐츠에 설명을 추가할 수도 있습니다.

let fs = require('fs'), path = require('path'), http = require('http'); const cache = {}; /** * lookup content type * infer from the extension * no extension would resolve in "text/plain" */ function lookupContentType(fileName) { const ext = fileName.toLowerCase().split('.').slice(1).pop(); switch (ext) { case 'txt': return 'text/plain'; case 'js': return 'text/javascript' case 'css': return 'text/css' case 'pdf': return 'application/pdf'; case 'jpg': case 'jpeg': return 'image/jpeg'; case 'mp4': return 'video/mp4'; default: return '' } } /** * plain 404 response */ function send404(res){ res.writeHead(404, {'Content-Type':'text/plain'}); res.write('Error 404: resource not found.'); res.end(); } /** * sending file response */ function sendFile(res, filePath, fileContents){ res.writeHead(200, {"Content-Type": lookupContentType(path.basename(filePath))}); res.end(fileContents); } /** * serve static content * using cache if possible */ function serveStatic(res, cache, absPath) { // use cache if there is any if (cache[absPath]) { sendFile(res, absPath, cache[absPath]); } else { fs.exists(absPath, function(fileExists) { // attempt to read the resource only if it exist if (fileExists) { fs.readFile(absPath, function(err, data){ // not able to read the resource if(err) { send404(res); } else { cache[absPath] = data; sendFile(res, absPath, data); } }); } else { // resource does not exist send404(res); } }); } } module.exports = function startServer(spec){ let { path, port } = spec; // create server object var server = http.createServer(function(req, res){ // if no resource is specified use index.html if(req.url === '/') { const filePath = path + 'index.html'; serveStatic(res, cache, filePath); } else { const filePath = path + req.url; serveStatic(res, cache, filePath); } }); server.listen(port, function(){ console.log("server listening on port: "+port); }); return server; };

이제 이렇게 실행할 수 있습니다.

const startServer = require('./startServer.js') startServer({ path: './static_content', port: 3000 });

위의 예에서 매우 기본적인 오류 처리를 추가했습니다. 사용자가 지정한 리소스가 정적 내용 디렉토리에서 없거나 읽기 위해 열 수 없는 경우, 오류 코드 404가 있는 다른 헤더와 잘못된 내용을 설명하는 다른 내용을 가진 서버 응답.

브라우저가 우리가 다루고 있는 콘텐츠의 종류를 더 잘 이해하려면 리소스 콘텐츠 유형에 대한 표시를 포함하는 것도 좋습니다. 조회 중콘텐츠형식 파일 확장자 유형을 기준으로만 수행할 수 있습니다.

이제 pdf로 시도하면 브라우저는 pdf 파일을 다운로드하는 대신 여는 데 문제가 없을 것입니다.

결론

이것은 결코 강력한 제품이 아니며, 익스프레스j와 같은 프레임워크에서 어떻게 일이 막후에서 작동하는지를 매우 단순화한 예에 불과하다. 우리는 라이브러리 http에 내장된 nodej를 활용하여 단순 http 서버를 실행했다.

우리는 주어진 위치에서 정적 콘텐츠를 찾기 위해 간단한 라우팅을 구현했다. 또한 리소스를 찾을 수 없거나 액세스할 수 없는 경우 메모리 캐싱, 컨텐츠 유형 해결 및 기본 오류 처리에서 단순성을 구현했습니다.

추가 읽기

정적 콘텐츠를 제공하는 자체 서버를 구축하려면 기존 프레임워크를 사용하는 것이 좋습니다. 또한 최소한 다음 주제에 대해 알아보는 것도 강력히 권고하고 싶다.

세션 및 트랜잭션 관리

캐싱

보안, 인증 및 승인

원천

nodejs/nodejs

넷캣

http의

상태 코드

일반 MIME 유형

from http://gong-tech.tistory.com/11 by ccl(A) rewrite - 2021-09-22 05:00:33