정적 파일 제공하기
이 튜터리얼은 hapi v17과 호환됩니다.
필연적으로 웹 응용프로그램을 만드는 동안 디스크에 있는 단순 파일을 제공해야 합니다. 추가 핸들러의 사용으로 hapi에 이 기능을 추가하는 inert라는 hapi 플러그인이 있습니다.
먼저 inert 설치와 프로젝트에 의존성을 추가해야 합니다.:
npm install --save @hapi/inert
h.file(path, [options])
먼저 h.file() 메소드를 사용하는 방법을 봅니다.:
const start = async () => {
await server.register(require('@hapi/inert'));
server.route({
method: 'GET',
path: '/picture.jpg',
handler: function (request, h) {
return h.file('/path/to/picture.jpg');
},
});
await server.start();
console.log('Server running at:', server.info.uri);
};
start();위에서 볼 수 있는 것처럼 가장 기본적인 형태로 h.file(path)를 반환하는 것입니다.
상대 경로
특히 파일로 응답하는 경로가 여러 개가 있다면, 단순하게 만들기 위해 서버 안에 기본 경로를 설정할 수 있고, 단지 상대 경로만 h.file()에 전달합니다.
'use strict';
const Hapi = require('@hapi/hapi');
const Path = require('path');
const server = Hapi.server({
routes: {
files: {
relativeTo: Path.join(__dirname, 'public'),
},
},
});
const start = async () => {
await server.register(require('@hapi/inert'));
server.route({
method: 'GET',
path: '/picture.jpg',
handler: function (request, h) {
return h.file('picture.jpg');
},
});
await server.start();
console.log('Server running at:', server.info.uri);
};
start();위와 같이 server.options.routes 아래의 옵션을 설정하면 모든 경로에 적용될 것입니다. 경로 수준에서 relativeTo 옵션을 포함하여 이 옵션을 설정할 수 있습니다.
파일 핸들러(handler)
위의 경로 대신 file 핸들러를 사용할 수 있습니다.:
server.route({
method: 'GET',
path: '/picture.jpg',
handler: {
file: 'picture.jpg',
},
});파일 핸들러 옵션
request 객체를 받아 파일의 경로(절대 또는 상대)를 문자열로 넘겨주는 함수를 인자로 지정할 수 있습니다:
server.route({
method: 'GET',
path: '/{filename}',
handler: {
file: function (request) {
return request.params.filename;
},
},
});path 속성을 가진 객체일 수도 있습니다. 객체 형식의 핸들러를 사용할 때, Content-Disposition 헤더 설정과 압축된 파일을 허용하는 것 같은 몇 가지 추가적인 것을 할 수 있습니다.
server.route({
method: 'GET',
path: '/script.js',
handler: {
file: {
path: 'script.js',
filename: 'client.js', // override the filename in the Content-Disposition header
mode: 'attachment', // specify the Content-Disposition is an attachment
lookupCompressed: true, // allow looking for script.js.gz if the request allows it
},
},
});디렉터리 핸들러
file 핸들러 외에 inert는 여러 파일을 제공하는 하나의 경로를 지정할 수 있는 directory 핸들러를 추가했습니다. 이를 사용하려면 인자를 가진 경로를 지정해야 합니다. 그러나 인자의 이름은 중요하지 않습니다. 인자에 별표(*) 확장을 사용하여 파일 깊이도 제약할 수 있습니다. directory 핸들러의 가장 기본적인 사용법은 다음과 같습니다.:
server.route({
method: 'GET',
path: '/{param*}',
handler: {
directory: {
path: 'directory-path-here',
},
},
});디렉터리 핸들러 옵션
위의 경로는 directory-path-here 디렉터리 안의 일치하는 파일 이름을 찾아 요청에 응답합니다. 이 설정에서 /에 대한 요청은 HTTP 403으로 응답할 것입니다. index 파일을 추가하여 이를 수정할 수 있습니다. 기본으로 hapi는 index.html으로 불리는 파일을 디렉터리에서 찾을 것입니다. index 옵션을 false로 설정하여 index 파일을 제공하지 않도록 할 수 있습니다. 또는 inert가 index 파일로 찾을 파일의 배열을 지정할 수 있습니다.
server.route({
method: 'GET',
path: '/{param*}',
handler: {
directory: {
path: 'directory-path-here',
index: ['index.html', 'default.html'],
},
},
});/에 대한 요청은 먼저 /index.html을 불러오려고 시도할 것이고, 그 다음에는 /default.html을 시도할 것입니다. 사용가능한 index 파일이 없다면 inert는 디렉터리의 내용을 목록 페이지로 보여줄 것입니다. 다음과 같이 listing 속성을 true로 설정하여 활성화 할 수 있습니다.:
server.route({
method: 'GET',
path: '/{param*}',
handler: {
directory: {
path: 'directory-path-here',
listing: true,
},
},
});이제 /에 대한 요청은 디렉터리의 내용을 보여주는 HTML로 응답할 것입니다. 목록이 활성화된 directory 핸들러를 사용할 때, 기본으로 숨겨진 파일들은 목록에서 보이지 않습니다. showHidden 옵션을 true로 설정하는 것으로 변경할 수 있습니다. file 핸들러처럼 directory 핸들러 또한 가능한 경우 미리 압축된 파일을 제공하는 lookupCompressed 옵션을 가지고 있습니다. 원래 경로를 찾지 못할 경우 요청에 추가되는 defaultExtension 옵션을 설정할 수 있습니다. /bacon에 대한 요청은 파일 /bacon.html에 대해서도 시도할 것입니다.