前端vue实现系统拦截跳转外链并进入跳转询问界面

跳转询问界面如下图所示:

给自己挖坑的实现方式,最终解决方案请看最底下 

思路:正常情况下我们有2种方式跳转外链

第一种非a标签,我们手动添加事件进行跳转

<div class="dingdan public-padding p-item" @click="goOtherWebsite('https://www.baidu.com/')">
     <span class="iconfont icon-shezhi" style="color: #818C99;"></span>
     <span>非a标签跳转外链</span>
</div>

 第二种a标签

<a href="https://www.baidu.com/" target="">a标签跳转外链</a>

第三种

1.分析下第一种

如果你不进入router,那你在跳转外链的时候vue框架的路由钩子不会监听到,因此我们从进router入手

a.新建一个中转询问页面linkWeb.vue,代码如下:

<template>
    <div class="link-container">
        <div class="content-box">
            <div class="content-title">即将跳转到外部网站</div>
            <div class="content-text">您将要访问的链接不属于本站点,请关注您的账号安全。</div>
            <div class="content-link">
            <div class="external-link-href">{{urlValue}}</div>
            </div>
            <div class="ui button orange external-link-btn" @click="jumpUrl()">继续前往</div>
        </div>
    </div>
</template>

<script>
export default{
    name: 'linkWeb',
    data() {
        return {
            urlValue:''
        }
    },
    mounted() {
        this.urlValue=this.$route.query.target
    },
    methods:{
        jumpUrl() {
            window.open(this.urlValue)
        }
    }
}
</script>

b.修改全局钩子函数beforeEach,代码如下:

router.beforeEach((to, from, next)=>{
  console.log('❤❤❤全局导航路由守卫❤❤❤~~~~~~~~~~~~',to)
  // console.log(to.path.indexOf('https:')==-1&&to.path.indexOf('http:')==-1)
  if(to.path.indexOf('https:')==-1&&to.path.indexOf('http:')==-1) {
    next();
  } else { // 处理外链
    console.log('处理外链')
    let tempLinkUrl=to.path
    if(tempLinkUrl.indexOf('/')!=-1&&tempLinkUrl.substr(0,1)=='/'){
      tempLinkUrl=tempLinkUrl.substr(1)
    }
    next({
      path: '/linkWeb',
      query:{
        target:tempLinkUrl
      }
    })
  }
})

注意,以上代码可能会报错,报错信息如:...via a navigation guard.,为解决此问题,我们需要在 Vue.use(Router)代码之前添加以下代码:

// 这段代码是为了解决跳转路由时报...via a navigation guard.的问题 start
const originalPush = Router.prototype.push
Router.prototype.push = function push (location, onResolve, onReject) {
  if (onResolve || onReject){
    return originalPush.call(this, location, onResolve, onReject)
  }
  return originalPush.call(this, location).catch(err => err)
}
// 这段代码是为了解决跳转路由时报...via a navigation guard.的问题 end

 

2.分析下第一种a标签跳转

我们需要手动禁止掉a标签默认的href属性跳转链接行为,将其转化为跳转我们自己的路由页面

关键代码如下:

mounted() {
      this.$nextTick(() => {
        document.querySelectorAll('a').forEach((item) => {
          item.addEventListener('click', this.linksPermissions)
        })
      })
    },
    beforeDestroy () {
      document.querySelectorAll('a').forEach((item) => {
        item.removeEventListener('click', this.linksPermissions)
      })
    },
    methods:{
      linksPermissions (e) {
        console.log('=== 禁止a标签跳转直接外部链接 ===', e.target.href)
        e.stopPropagation()
        e.preventDefault()
        this.$router.push({
            path: e.target.href
        });
      }

本来一切都进行的ok了,功能也都实现了,但突然发现有一个致命的问题:如果配置了{ path: '*', component: NotFound }匹配404界面,那以上全局路由守卫的代码完全就失效了,没有任何意义,跳外链的时候直接就匹配到404的路由上去了

失效了💀💀💀💀💀💀💀💀💀💀💀💀💀💀

最终解决方案如下👇👇👇👇👇👇👇👇👇👇👇👇:

进行路由动态匹配,通过“路由独享的守卫”来控制重定向到询问页面,关键代码如下:

// 将匹配以 `/http` 开头的所有路由
    { 
      path: '/http:afterUser(.*)',
      redirect: to => { // 带参数重定向
        // console.log(to)
        let tempLinkUrl=to.path
        if(tempLinkUrl.indexOf('/')!=-1&&tempLinkUrl.substr(0,1)=='/'){
          tempLinkUrl=tempLinkUrl.substr(1)
        }
        // 方法接收目标路由作为参数
        // return 重定向的字符串路径/路径对象
        return { path: '/linkWeb', query: { target:tempLinkUrl } }
      }
    },

把全局导航路由守卫恢复如初:

 前端路漫漫,菜鸟还需加油冲,完结撒花!🌸🌸🌸🌸🌸🌸

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

唐小亭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值