티스토리 뷰

Vue.JS

[vue-router] HTML5 히스토리 모드

버미노트 2019. 6. 14. 00:04

vue-router의 기본 설정은 hash 모드입니다. URL 해시를 사용하기 때문에 URL이 변경될 때 페이지가 다시 로드되지 않습니다.
해시를 제거하기 위해 vue-router는 history 모드도 지원합니다. history.pushState API를 사용하여 페이지를 다시 로드하지 않고 URL을 변경 할 수 있습니다.

const router = new VueRouter({
  mode: 'history',
  routes: [...]
})

위의 코드와 같이 history 모드로 설정 할 수 있습니다. history 모드를 사용할 때, 처음 경로 부터 쭉~ 사용한다면 문제없이 정상적으로 동작합니다. 하지만 중간 경로로 직접 접속하면 404 오류가 발생합니다. http://서버주소/user/1와 같은 URL로 바로 접속하면 404 오류가 발생합니다. (hash 모드를 사용하면 이런 오류가 없긴 합니다.) 이런 문제를 해결하려면 서버에서 어떠한 경로로 접근하더라도 index.html 페이지를 제공해야 합니다.

1. 서버 설정

Apache


  RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /index.html [L]

nginx

location / {
  try_files $uri $uri/ /index.html;
}

Native Node.js

const http = require("http")
const fs = require("fs")
const httpPort = 80

http.createServer((req, res) => {
  fs.readFile("index.htm", "utf-8", (err, content) => {
    if (err) {
      console.log('We cannot open "index.htm" file.')
    }

    res.writeHead(200, {
      "Content-Type": "text/html; charset=utf-8"
    })

    res.end(content)
  })
}).listen(httpPort, () => {
  console.log("Server listening on: http://localhost:%s", httpPort)
})

IIS

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <rewrite>
      <rules>
        <rule name="Handle History Mode and custom 404/500" stopProcessing="true">
          <match url="(.*)" />
          <conditions logicalGrouping="MatchAll">
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
          </conditions>
          <action type="Rewrite" url="/" />
        </rule>
      </rules>
    </rewrite>
  </system.webServer>
</configuration>

IIS UrlRewrite를 설치한 후, 위의 코드와 같이 web.config에 설정합니다.

Caddy

rewrite {
    regexp .*
    to {path} /
}

Firebase hosting

{
  "hosting": {
    "public": "dist",
    "rewrites": [
      {
        "source": "**",
        "destination": "/index.html"
      }
    ]
  }
}

firebase.json에 위의 코드와 같이 설정합니다.

2. 주의 사항

위의 이야기 했던 것과 같이 서버를 설정하였다면, 모든 경로가 index.html를 제공하기 때문에 이제는 404 오류를 확인 할 수 없습니다.

const router = new VueRouter({
  mode: 'history',
  routes: [
    { path: '*', component: NotFoundComponent }
  ]
})

이 문제를 해결하기 위해서는 위의 코드와 같이 catch-all 라우터를 구현하여 404 페이지를 만들어야 합니다. 자세한 내용은 [vue-router] 동적 라우트 매칭을 참고 바랍니다.

참고

댓글
공지사항
최근에 올라온 글