Nuxt 使用双冒号编码/解码 URI
Posted
技术标签:
【中文标题】Nuxt 使用双冒号编码/解码 URI【英文标题】:Nuxt encode/decode URI with double colon 【发布时间】:2020-03-20 23:38:43 【问题描述】:我的网址上有双冒号。
我将路径推送到 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
欢迎提出建议
【问题讨论】:
:
不是有效的 URL 字符。
***.com/questions/2053132/…
为什么不使用/towns/3
它是内置和标准的
你说得对,这可能更容易,但我无法自己更改 URI 格式@LawrenceCherone
您能否为您的陈述提供参考?在这种情况下,您可以将其发布为答案,我很乐意接受@tony19
【参考方案1】:
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-router
(path-to-regexp
) 正在使用 :
来“标记”命名路径参数......没有办法解决它
你可以看看this sandbox。它不是 Nuxt,但我很确定它会以同样的方式在 Nuxt 中工作....
更新
嗯,它在 Nuxt 中确实不起作用。似乎 Nuxt 出于某种原因在匹配的路径段上应用 encodeURIComponent()
并引发错误。它在服务器端渲染时工作(它仍然在客户端引发一些错误)......
【讨论】:
没关系。根据需要更改您的正则表达式,只需确保在其前面加上:myparamname
以便 vue-router
使您可以在 $route.params.myparamname
中使用正则表达式结果
不幸的是,对于 Nuxt,这不起作用(收到我在上面分享的错误消息)。不过非常感谢您的反馈
是的,这就是它的行为方式(在发布之前,我尝试了path: '*' + 'towns' + decodeURIComponent('(:[0-9].*)?/'),
,但得到了相同的错误消息)。
更改path
无济于事。路由定义中:
没有问题。问题在于在导航期间与该路径匹配的实际 url(来自浏览器导航栏或来自 nuxt-link
)的代码。这是 Nuxt 恕我直言的错误......【参考方案2】:
首先,我同意Michal Levý's answer,这里有一个库错误。 Nuxt 源代码中出现错误的行在这里:
https://github.com/nuxt/nuxt.js/blob/112d836e6ebbf1bd0fbde3d7c006d4d88577aadf/packages/vue-app/template/utils.js#L523
您会注意到该段的几行已编码,导致:
切换到%3A
。
但是,这条线似乎起源于 path-to-regexp:
https://github.com/pillarjs/path-to-regexp/blob/v1.7.0/index.js#L212
修复此错误并非易事,因为编码不仅仅是“错误”。这里发生了很多事情,当到达该行时,参数值已从其原始值进行 URL 解码。在我们未编码的:
导致问题的情况下,但在其他情况下,例如匹配%3A
,则需要编码。
path-to-regexp 中的编码处理是一个微妙的话题,使用的旧版本对我们没有帮助。这也使得在您的应用程序中找到合适的解决方法变得更加困难。
那么,让我们看看我们能做些什么......
首先,让我们考虑路径:
path: 'towns' + '(:[0-9].*)?/',
这样连接字符串有点奇怪,所以我要把它们组合起来:
path: 'towns(:[0-9].*)?/',
最后的/
并没有受到伤害,但就这个问题而言,这似乎是不必要的噪音,所以我将放弃它。
另一方面,开头没有/
会导致严重问题,所以我要添加一个。
.*
也很可疑。你真的是说匹配任何东西?例如当前路由将匹配towns:3abcd
。这真的是你想要的吗?我的怀疑是你只想匹配数字。例如towns:3214
。为此,我使用了[0-9]+
。
剩下的就是:
path: '/towns(:[0-9]+)?',
现在,:
问题。
通常,路由路径用于两个方向:匹配/解析 URL 和构建 URL。您对未命名参数的使用让我想知道您是否仅打算将此路由用于匹配目的。
一个选项可能是这样的:
path: '/towns:([0-9]+)',
通过将:
移到参数之外,它可以避免编码问题。
上面的代码有两个问题:
-
URL 上的冒号/数字后缀不再是可选的。即它不会像原始路由那样匹配路径
/towns
。这可以通过将/towns
注册为单独的路由来解决。我不知道有任何其他方法可以使用可用的 path-to-regexp 版本解决此问题。
您将无法使用它来构建 URL,例如nuxt-link
。
如果您也需要能够使用它来构建 URL,那么您可以使用命名参数:
path: '/towns::town([0-9]+)',
这里的::
部分可能会造成混淆。第一个:
按字面意思处理,而第二个:
用作town
参数的前缀。然后,您可以像这样将其与 nuxt-link
一起使用:
<NuxtLink :to=" name: 'custom', params: town: 4 ">
...
</NuxtLink>
【讨论】:
有趣的解决方案。使用 Vue Router 比我的要好得多。但不幸的是,最后一个示例在 Nuxt 中仍然不起作用。链接有效(参数传递给目标组件),但href
呈现为/towns::
,因此刷新后参数丢失....
@MichalLevý 有趣。我自己没有看到这个问题。我从原始问题中克隆了 GitHub 存储库,所以我使用的是 Nuxt 2.10.2 和 Vue Router 3.0.7。我最初确实尝试使用path: '/towns\\::town([0-9]+)',
作为一种明确转义第一个冒号的方法,但它似乎没有必要,所以我没有将它包含在我的答案中。由于我无法重现您看到的问题,因此很难知道从哪里开始尝试调试它...
没关系。我在 Codesandbox 中测试它,它显然有它的怪癖。重新启动容器后,它就像一个魅力。好工作!这应该被接受的答案...以上是关于Nuxt 使用双冒号编码/解码 URI的主要内容,如果未能解决你的问题,请参考以下文章
encodeURI , encodeURIComponent , decodeURL , decodeURIComponent 转码与解码