问题
在修复 #563 时,我发现e2e tests 里包含SSR时,相对路径的redirect。
一般来说,我们的功能应该是同构的,因为我也增加了CSR的对应e2e test,随后发现CSR时,相对路径的redirect无法正常工作。
例子
具体来说。
SSR 相对路径的redirect 的test case,是正常的。假设我们有以下页面
/
/c
/x
,其loader会return redirect('c')
即相对路径redirect
/x/c
当SSR时,直接访问/x
,会302到/x/c
,相当于,此次redirect是基于/x
的。这是我们的当前预期。
然而,当前端路由跳转时,如,在/
页面,点击/x
的链接,结果却跳到了/c
页面,也就是说,此处redirect是基于跳转前的路径/
同时,当在SPA模式下,直接访问/x
,页面url会跳转至/x/c
,但是页面显示404。这里应该是另一个bug
也就是说,对于同一个页面,不同情况下的访问表现出截然不同的行为。
分析
我认为,相对路径的redirect,是一个bad practice。
通常来说,前端路由导航由页面中的链接按钮触发,当点击链接导航时,可以是相对路径,并且是由跳转之前的url为base url。
也就是说,对于单纯的路由导航,其跳转地址可以是相对路径,并且规则很明确。
但是对于redirect,情况则不同了。
前端路由导航中下,redirect 包含三个对象:
- navigate from
- navigate to
- redirect to
如果redirect地址是一个相对路径,那么,这个是相对于navigate from,还是navigate to呢?我认为规则是不清晰的。
shuvi允许在loader中进行redirect。对于开发者来说,如果使用相对路径进行redirect,自然想到的是以loader所在的路由作为base。
但事实上,loader所在的路由是navigate to。
在上面的例子中(shuvi 的 e2e test中),SSR时访问/x
,redirect至 /x/c
,正是以 navigate to 作为base。
而前端路由跳转时,却redirect到 /c
,此时则变成了以 navigate from 作为base。vue-router 也是如此。
其他框架的做法
使用相对路径进行redirect时,vue 的 base 是navigate from
remix 和react-router 是基于 navigate to
next.js 待确认
解决方案
相对来说,我倾向于以navigate to 作为base,比较符合直觉。
因为,无论是使用route config还是使用hook,还是loader来配置redirect。
redirect总是配置在navigate to上面的。
而navigate to是很明确的,所以这时如果有redirect,自然是应该基于当前的navigate to来计算实际路径。
另一方面,用户在跳转时,navigate from可以是任何地址。如果redirect的相对路径base是navigate from,那么最终地址也是五花八门的,是完全不可预料的,这样也就没有意义了。