- Spring Boot 쇼핑몰 프로젝트 메인 페이지에서 상품 이미지를 불러올 때 "file:///" 문법에 대한 궁금증
file URI scheme
위키피디아 문서
file URI 구조는 RFC 8089에서 정의 되었으며 보통 소유자의 컴퓨터(Local)에서 파일을 찾기위해 사용된다.
"file://host/path" 포맷을 취하는데 host는 시스템의 fully qualified domain name 이며
여기서 path 에 접근 가능하다.(=Ip/Path) 또한 Path 는 계층 구조를 띤다.
만약 host 부분이 생략된다면, 해당 URL이 수행되는 컴퓨터인 "localhost" 로 자동 지정된다.
하지만 host 부분이 생략된다고 해서 slash 도 생략되는 것이 아니기 때문에 "file:///: 이 유효한 문법이다.
"file" 뒤에 "//"(두개의 slash)는 뒤에 호스트네임 또는 localhost 가 온다는 것을 의미하며 종종 생략된다.
host 부분과 path 부분 사이의 "/"(한개의 slash)는 URI에서 로컬 경로의 시작을 의미하고 생략되서는 안된다.
따라서 유효한 file URI 는 file:/path 로 시작하거나 file:/// path 또는 file//hostname/path 가 되어야 한다.
- "file://hostname/path" 문법은 로컬에서 파일을 찾는 URI 프로토콜이며 hostname 부분은 생략이 가능하기 때문에 종종 file:/path 또는 file:///path 로 쓰임
StackOverflow 1
스택오버플로우 질문 및 답변
보안상의 이유로, 많은 브라우저는 서버로부터 받은 (서버의)파일에서 서버의 로컬 파일로 접근하는 것을 허락하지 않는다.
따라서 HTTP를 통해 받은 페이지에서 주소창에 해당 구조로 서버의 로컬파일을 요청하게 되면 제대로 동작이 되지 않을 것이다.
- 위키피디아 내용과 비슷하며, 보안상의 이유로 외부에서 file: URL 을 통해 다른 로컬로 접근한다면 에러가 발생함
- localhost 로 파일에 접근하면 정상적으로 동작하지만, ip 를 직접 입력하여 외부에서 접근하는 것처럼 접근한다면 에러 발생
StackOverflow 2
스택오버플로우 질문 및 답변
간단하게 마랗면 "file://" 부분은 프로토콜이고 "/" 부분은 루트 디렉토리를 의미한다.
예를들어, "http://google.com" 에서 "http://" 부분은 프로토콜이고 "google.com" 은 루트 디렉토리를 의미함
- "file://" 는 이해할 원리가 없는 단순 프로토콜 규칙이며 뒤에 오는 "/" 는 루트 디렉토리(로컬)을 의미함
결론
- 궁금했던 "file:///" 문법은 로컬에서 파일을 찾을 때 사용되는 file URI 이다.
- "file://" 부분은 단순 프로토콜 규칙이며 뒤에는 hostname 이 들어오는데 종종 생략된다.
- 따라서 "file:///path", "file:/path", "file://hostname/path" 가 유효한 문법이며 생략된 hostname 은 localhost 로 매핑된다.
추가적으로 알게 된 사실
- Spring 정적 파일 접근부분에서 Tomcat web.xml 파일의 url 설정에 따른 동작 원리
- " /* " : 모든 url 요청을 스프링 디스패처가 dispatcher-servlet.xml 에 존재하는 Bean 으로만 처리
- " / " : dispatcher-servlet.xml 에 매핑되는 Bean 이 없다면 정적파일 접근으로 처리
- 하지만 서버의 정적파일을 경로를 지정해 직접 접근하는 것은 좋지 않기 때문에 View 파일은 webapp/WEB-INF 안에 숨기는 것이고 추가적인 정적 파일들은 static 폴더에 저장
- 컨트롤러에 매핑되지 않는 요청은 정적파일 요청이므로
"/**"
패턴의 URL 요청 (=모든 요청)은 /static/
폴더를 기준으로 탐색하게끔 지정
<mvc:resources location="/static/" mapping="/**"></mvc:resources>
- 즉, 서버의 파일 저장 경로를 직접 지정하여 http Get 방식의 요청을 보내면 해당 파일을 반환 받을 수 있으므로 정적파일을 핸들링하는 부분에서 location 을 무조건 file:URI 로 설정하지 않아도 됨
추가적인 궁금증
- 위와 비슷한 방식으로 해서 http 요청으로도 정적파일을 받아올 수 있을 것 같은데 굳이 file:URI 를 이용해서 상품 이미지를 찾은 이유가 뭘까? 라는 궁금증이 생김.
- 궁금증 해결
- 파일을 찾을 때 서버(로컬 컴퓨터)의 루트를 기준으로 찾는게 아니라 프로젝트의 루트를 기준으로 찾음
- "http://localhost/Users/codren/study/item/파일명" 요청이 404 Not Found 에러가 난 이유는 상품이미지가 프로젝트 내부가 아니라 외부에 저장되어있기 때문임
- 그렇기 때문에 프로젝트 내부가 아닌 외부의 파일을 찾기 위해서 file: URI 를 사용한 것이며 만약에 프로젝트 내부에 존재한다면 file: URI 를 사용하지 않아도 될 것으로 보임