Unexpected token '<', 원인은 HTML일까?
자바스크립트를 실행했는데 SyntaxError: Unexpected token '<'라는 오류가 나타나면 조금 이상하게 느껴집니다. 자바스크립트 파일에는 <를 작성한 적도 없는데 갑자기 HTML 태그처럼 생긴 문자가 문제라고 나오기 때문인데요.
결론부터 말하면 Unexpected token '<'는 HTML이 원인인 경우가 많습니다.
정확히는 자바스크립트나 JSON을 받아야 하는 곳에서 서버가 HTML 문서를 반환했고, 이를 JavaScript 또는 JSON으로 해석하려다 오류가 발생하는 상황입니다.
왜 이런 일이 생기는지부터 해결 순서까지 자세히 알아보겠습니다.
Unexpected token '<' 뜻은?
Unexpected token은 자바스크립트 엔진이 코드를 해석하다가 현재 위치에서 예상하지 못한 문자를 발견했다는 의미입니다. 여기서 문제의 문자가 <라면 HTML의 시작 태그를 의심해볼 수 있습니다.
<!DOCTYPE html>
<html>
<head>
...
</head>
</html>
HTML 문서는 대부분 <!DOCTYPE html>이나 <html>처럼 <로 시작합니다. 그런데 브라우저가 이 내용을 자바스크립트라고 생각하고 읽는다면 첫 번째 <부터 문법적으로 이해하지 못해 오류가 발생할 수 있습니다.
쉽게 말하면 “JavaScript가 올 줄 알았는데 열어보니 HTML이었다”라고 이해하면 됩니다.
Unexpected token '<' 원인 1, JS 파일 경로 오류
가장 먼저 확인할 것은 자바스크립트 파일의 경로입니다. HTML에서 존재하지 않는 JS 파일을 요청하면 서버 설정에 따라 404 페이지나 기본 HTML 문서가 반환될 수 있습니다.
<script src="/js/app.js"></script>
예를 들어 실제 파일은 다른 폴더에 있는데 위 주소로 요청했다면 서버가 app.js 대신 HTML 오류 페이지를 보낼 수 있습니다. 브라우저는 그 HTML을 자바스크립트로 실행하려다가 <에서 SyntaxError를 발생시키는 것이죠.
따라서 파일명뿐 아니라 상대 경로와 절대 경로, 대소문자, 실제 배포된 파일 위치까지 함께 확인하는 것이 좋습니다.
API에서 Unexpected token '<'가 발생하는 이유
API를 호출한 뒤 JSON으로 변환하는 과정에서도 비슷한 오류를 자주 만날 수 있습니다. 프로그램은 JSON 응답을 예상했지만 실제 서버에서는 HTML 오류 페이지나 로그인 페이지를 반환한 경우입니다.
fetch("/api/users")
.then(response => response.json())
.then(data => console.log(data));
정상이라면 서버에서 JSON 데이터가 반환되어야 합니다. 하지만 API 주소가 틀렸거나 서버 오류, 인증 문제, 리다이렉트 등이 발생해 HTML이 반환됐다면 JSON 파싱 단계에서 오류가 발생할 수 있습니다.
환경에 따라 이 경우 Unexpected token '<'뿐 아니라 "<!DOCTYPE "... is not valid JSON처럼 조금 다른 메시지가 표시되기도 합니다.
메시지는 달라도 실제 응답이 JSON인지 확인해야 한다는 점은 같습니다.
Unexpected token '<' 주요 원인 7가지
1. JavaScript 파일 경로가 잘못된 경우
존재하지 않는 JS 파일을 요청하면서 서버의 404 HTML 페이지를 전달받는 대표적인 상황입니다.
2. API 주소가 잘못된 경우
JSON API가 아닌 웹페이지 주소를 호출했거나 엔드포인트를 잘못 작성하면 HTML이 반환될 수 있습니다.
3. 개발 서버의 라우팅 설정 문제
React, Vue 등의 SPA 개발 환경에서는 알 수 없는 경로를 index.html로 보내도록 설정하기도 합니다. JS 파일이나 API 요청까지 잘못 fallback되면 HTML 응답을 받을 수 있습니다.
4. 배포 후 파일 경로가 달라진 경우
로컬에서는 정상인데 배포 후에만 오류가 발생한다면 base path, public path 또는 정적 파일 경로 설정을 확인해 보세요.
5. 로그인 페이지로 리다이렉트된 경우
인증이 필요한 API에 로그인하지 않은 상태로 접근하면 서버가 JSON 대신 로그인 HTML 페이지로 이동시킬 수 있습니다.
6. 서버 오류 페이지가 반환된 경우
서버 내부 오류가 발생하면서 애플리케이션이 예상한 JSON 대신 HTML 형식의 에러 페이지를 반환하는 경우도 있습니다.
7. HTML 파일을 JS로 잘못 불러온 경우script src 등에 실수로 HTML 파일을 지정했거나 서버의 MIME type 및 정적 파일 설정이 잘못된 상황도 확인할 필요가 있습니다.
Network 탭에서 HTML 응답 확인하기
이 오류를 가장 빠르게 해결하는 방법 중 하나는 브라우저 개발자 도구의 Network 탭을 확인하는 것입니다. Chrome이나 Edge 등에서 F12를 눌러 개발자 도구를 연 뒤 문제가 되는 JS 또는 API 요청을 찾아보세요.
해당 요청의 Response를 확인했을 때 다음처럼 HTML이 보인다면 중요한 단서를 찾은 것입니다.
<!DOCTYPE html>
<html>
...
</html>
이후 Request URL, Status Code, Content-Type, Response를 차례대로 살펴보세요. 404라면 경로 문제를, 401이나 403이라면 인증·권한 문제를, 3xx 응답이라면 리다이렉트 여부를 의심해볼 수 있습니다.
Unexpected token '<' 해결 순서 7단계
오류가 발생했다고 자바스크립트 문법부터 계속 수정할 필요는 없습니다. 실제 문제는 서버가 잘못된 파일이나 응답을 보내고 있는 경우가 많기 때문입니다.
| 순서 | 확인할 내용 |
| 1단계 | 콘솔에서 오류가 발생한 파일 또는 요청 확인 |
| 2단계 | 개발자 도구의 Network 탭 열기 |
| 3단계 | 문제가 된 요청의 Response 확인 |
| 4단계 | HTML이 반환됐는지 확인 |
| 5단계 | URL과 HTTP 상태 코드 확인 |
| 6단계 | 라우팅·인증·정적 파일 설정 확인 |
| 7단계 | 수정 후 새로고침하여 다시 요청 |
React·Vue에서 발생했다면 무엇을 볼까?
React나 Vue 프로젝트에서는 개발 서버와 SPA 라우팅 때문에 이 오류를 만날 수 있습니다. 존재하지 않는 정적 파일 경로를 요청했는데 서버가 index.html을 반환하면 브라우저는 HTML을 JS로 처리하려고 할 수 있습니다.
Vite, Webpack 등의 빌드 도구를 사용한다면 base 경로, 정적 파일 위치, 빌드 결과물의 실제 경로를 확인해 보세요. 로컬에서는 정상인데 운영 서버에서만 오류가 발생한다면 배포 경로와 서버의 fallback 설정도 중요한 확인 대상입니다.
JSON 오류라면 response.json() 전에 확인하세요
API 문제를 디버깅할 때는 응답을 바로 JSON으로 변환하기 전에 HTTP 상태와 Content-Type을 확인하는 방법도 유용합니다.
const response = await fetch("/api/users");
if (!response.ok) {
throw new Error(`HTTP error: ${response.status}`);
}
const contentType = response.headers.get("content-type");
if (!contentType?.includes("application/json")) {
throw new Error("JSON 응답이 아닙니다.");
}
const data = await response.json();
이렇게 작성하면 서버가 예상과 다른 응답을 반환했을 때 원인을 조금 더 명확하게 구분할 수 있습니다. 특히 API를 개발할 때는 성공 응답뿐 아니라 오류 응답도 가능한 한 일관된 형식으로 설계하는 것이 좋습니다.
Unexpected token '<' 핵심 해결법
Unexpected token '<'가 보인다면 가장 먼저 “HTML이 반환된 것은 아닐까?”라고 생각해 보세요. 자바스크립트 파일 경로 오류, API 주소 오류, 404 페이지, 로그인 리다이렉트, SPA fallback 등이 대표적인 원인입니다.
핵심은 코드만 들여다보는 것이 아니라 개발자 도구의 Network 탭에서 실제로 서버가 무엇을 반환했는지 확인하는 것입니다. Response에 <!DOCTYPE html>이나 <html>이 보인다면 URL과 서버 설정을 중심으로 추적해 보세요.
앞서 살펴본 일반적인 Unexpected token과 달리 <가 명시된 오류는 네트워크 응답이나 파일 경로에서 원인을 찾는 경우가 많습니다. 이 차이만 기억해도 문제를 해결하는 시간이 훨씬 짧아질 수 있습니다.