Skip to content

Properly encode/decode the percentage character (% -> %25) across browsers and upon initial navigation #2725

Closed
@posva

Description

@posva

Currently, the percentage character creates multiple issues and inconsistencies. This is partly due to:

In Vue router, we have multiple inconsistencies between asterisk path, param paths and regular path regarding escaping these characters and whether the navigation is initial or triggered by a push/router-link

Given this set of routes in history mode

[
  { path: '/foo/:p', component: Foo },
  {
    path: '*',
    component: Other,
  },
]

History mode / Chrome, IE 11,10

to route match href produced in router-link $router info after clicking $router info on direct navigation remarks
/%7D * /%7D /%7D - /} /} - /} User should write /} as the link instead
/} * /%7D /} - /} N/A (browser should encode it te be /%7D) -
/%25 * /%25 /%25 - /% ERROR Navigation should be possible. Should user also write /% to be consistent?
/% * ERROR N/A (not working) N/A (not valid) Or should they escape the percent themselves because it's the only special character
/foo/%7D /foo/:p /%7D /%7D - p = } /} - p = } User should write /foo/}
/foo/} /foo/:p /%7D /} - p = } /} - p = }
/foo/%25 /foo/:p /%25 /%25 - p = % ERROR Navigation should be possible

Hash mode / TODO

Query / TODO


Complete html file to test. Requires a vue-router.js file in the same folder

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
  </head>

  <body>
    <script src="https://unpkg.com/vue"></script>
    <!-- <script src="https://unpkg.com/vue-router"></script> -->
    <script src="/vue-router.js"></script>

    <div id="app">
      <pre>{{ $route.path }}</pre>
      <pre>{{ $route.params }}</pre>
      <router-link to="/">/home</router-link>
      <router-link to="/%7D">/%7D</router-link>
      <router-link to="/}">/}</router-link>
      <router-link to="/%25">/%25</router-link>
      <!-- <router-link to="/%">/%</router-link> -->
      <router-link to="/foo/%7D">/foo/%7D</router-link>
      <router-link to="/foo/}">/foo/}</router-link>
      <!-- <router-link to="/foo/%">/foo/%</router-link> -->
      <router-link to="/foo/%25">/foo/%25</router-link>
      <router-view></router-view>
    </div>

    <script>
      var Home = { template: '<div>Home</div>' }
      var Foo = { template: '<div>Foo: {{ $route.params.p }}</div>' }
      var Other = {
        template: '<div>Other: {{ $route.fullPath }}</div>',
      }
      var router = new VueRouter({
        mode: 'history',
        routes: [
          { path: '/', component: Home },
          { path: '/foo/:p', component: Foo },
          {
            path: '*',
            component: Other,
          },
        ],
      })

      new Vue({
        router: router,
        el: '#app',
      })
    </script>
  </body>
</html>

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugdiscussionfixed on 4.xThis issue has been already fixed on the v4 but exists in v3

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions