Nuxt使用双冒号编码/解码URI

时间:2019-11-25 16:12:06

标签: vue.js nuxt.js nuxt

我的网址上有两个冒号。

我将路径推送到其中包含的Nuxt路由器。

  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

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

如何将其还原为

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

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

欢迎提出任何建议

2 个答案:

答案 0 :(得分:6)

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

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

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

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

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

您可以查看this sandbox。它不是Nuxt,但是我很确定它也可以以Nuxt的方式工作。...

更新

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

答案 1 :(得分:3)

首先,我同意Michal Levý's answer的观点,这是一个库错误。抛出错误的行在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,则需要进行编码。

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

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

首先,让我们考虑一下路径:

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

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

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

最后的/并没有什么坏处,但是对于这个问题而言,这似乎不是多余的声音,因此我将其删除。

另一方面,开始时没有/可能会导致重大问题,因此我将添加一个。

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

这给我们留下了

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

现在,:问题。

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

一个选项可能是这样:

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

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

上面的代码有两个问题:

  1. 冒号/数字后缀在URL上不再是可选的。也就是说,它将与原始路线不匹配路径/towns。这可以通过将/towns注册为单独的路由来解决。我不知道有其他可用现有版本的正则表达式路径来解决此问题的方法。
  2. 您将无法使用它来构建网址,例如与nuxt-link

如果还需要使用它来构建URL,则可以改用命名参数:

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

此处的::部分可能令人困惑。第一个:按字面意义处理,而第二个:用作town参数的前缀。然后,您可以像这样将其与nuxt-link一起使用:

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