关于vue.js:用双冒号对URI进行Nuxt编码/解码

Nuxt encode/decode URI with double colon

我的网址上有两个冒号。

我将路径推到具有:的Nuxt路由器。

1
2
3
4
5
6
7
8
9
10
11
  export default {
  router: {
    extendRoutes (routes, resolve) {
      routes.push({
        name: 'custom',
        path: 'towns' + '(:[0-9].*)?/',
        component: resolve(__dirname, 'pages/404.vue')
      })
    }
  }
}

例如,当我指向http:// localhost:3000 / towns:3时,在导致此错误消息的URL上将:转换为%3A

1
Expected"1" to match":[0-9].*", but received"%3A2"

如何将其还原为:?

我徒劳地尝试了encodeURI(),decodeURI(),encodeURIComponent()和decodeURIComponent()。

针对想要尝试的人的演示:nuxt-extend-routes

欢迎任何建议


Vuex使用vue-router,vue-router使用path-to-regexp解析路由器路径配置

在我看来,您正在尝试使用无名参数,这是没有意义的,因为vue-router / vuex需要该参数的名称才能将其向下传递给路由后面的Vue组件

为什么不只使用命名参数?

1
2
3
4
5
{
      path: '/towns:id(:\\\\d+)',
      name: 'Page 3',
      component: Page3
    }

当然,结果是$route.params.id值将带有:前缀,并且所有router-link参数必须为:XX而不是'XX',但这是您可以处理的。 vue-router(path-to-regexp)使用:来"标记"已命名的路径参数...没有办法解决

您可以查看此沙箱。它不是Nuxt,但我很确定它可以以相同的方式在Nuxt中工作....

更新资料

嗯,在Nuxt中它实际上不起作用。看来Nuxt出于某种原因在匹配的路径段上应用了encodeURIComponent()并抛出错误。它在服务器端渲染tho时起作用(它仍然在客户端上引发一些错误)...


首先,我同意Michal Lev ??的回答,即此处存在库错误。在Nuxt源代码中,抛出错误的行在这里:

https://github.com/nuxt/nuxt.js/blob/112d836e6ebbf1bd0fbde3d7c006d4d88577aadf/packages/vue-app/template/utils.js#L523

您会注意到该段的几行已编码,导致:切换到%3A

但是,此行似乎起源于正则表达式路径:

https://github.com/pillarjs/path-to-regexp/blob/v1.7.0/index.js#L212

修复此错误并非易事,因为编码不是简单的"错误"。这里有很多事情发生,直到到达该行时,参数值已经从其原始值进行了URL解码。如果我们的未编码:导致问题,但在其他情况下(例如匹配%3A),则需要进行编码。

到正则表达式路径中的编码处理是一个微妙的话题,使用的旧版本对我们没有帮助。这也使得在您的应用程序中提出合适的解决方法变得更加困难。

所以,让我们看看我们能做什么...

首先,让我们考虑路径:

1
path: 'towns' + '(:[0-9].*)?/',

有点奇怪,可以像这样连接字符串,所以我将把它们组合起来:

1
path: 'towns(:[0-9].*)?/',

最后的/并没有受到伤害,但对于该问题而言似乎不是多余的噪音,因此我将其删除。

反面,开始时没有/可能会导致严重问题,因此我要添加一个。

.*也是可疑的。你真的是说匹配任何东西吗?例如当前路线将匹配towns:3abcd。那真的是你想要的吗?我怀疑您只想匹配数字。例如towns:3214。为此,我使用了[0-9]+

这让我们有了:

1
path: '/towns(:[0-9]+)?',

现在是:问题。

通常,在两个方向上都使用路由路径:匹配/解析URL并构建URL。您对未命名参数的使用使我想知道您是否仅打算将此路由用于匹配目的。

一个选项可能是这样:

1
path: '/towns:([0-9]+)',

通过将:移动到参数之外,可以避免编码问题。

上面的代码有两个问题:

  • URL上的冒号/数字后缀不再是可选的。即与原始路径不匹配路径/towns。这可以通过将/towns注册为单独的路径来解决。我不知道有其他可用路径到正则表达式的版本来解决此问题的方法。
  • 您将无法使用它来构建网址,例如与nuxt-link
  • 如果还需要使用它来构建URL,则可以改用命名参数:

    1
    path: '/towns::town([0-9]+)',

    此处的::部分可能会造成混淆。第一个:按字面意义处理,而第二个:用作town参数的前缀。然后,您可以将其与nuxt-link一起使用,如下所示:

    1
    2
    3
    <NuxtLink :to="{ name: 'custom', params: { town: 4 } }">
     ...
    </NuxtLink>