场景描述
产品要求开发一个落地页,为了美观,他要求这个两个页面分开设计,PC页面路由是`/landingpage`,移动端页面是`/landingpage/mobile`
从用户角度出发,现在有一种访问场景,假如用户A正在访问PC页面`/landingpage`,然后他要把这个页面以微信方式分享给用户B,用户通过手机方式打开,那这个时候用户用手机看到的就是PC端页面
要解决上面的场景问题,有以下几种方案
1. 在页面上利用`getServerSideProps` 进行定向,弊端:假如我有很多这样的页面,那就要在每个页面写相同的重定向代码
2. 写通用逻辑hooks判断当前环境,根据环境跳转至不同的路由,弊端:hooks是客户端方法,要执行该方法首先的进入浏览器客户端,然后根据条件跳转不同的地址,这个时候就会出现闪烁
3. 利用中间件(middleware.ts)可实现丝滑无感跳转,原理就是重定向
hooks版本
useMobileAndPcBridging.ts
import { useRouter } from 'next/router' const PC_MOBILE_LIST = [ ['/landingpage/amazon', '/landingpage/amazon/mobile'], ['/landingpage/goOut', '/landingpage/goOut/mobile'], ['/landingpage/vppa', '/landingpage/vppa/mobile'], ['/gec/introduce', '/gec/introduce/mobile'], ['/greenCertificate/introduce', '/greenCertificate/introduce/mobile'], ['/landingpage/intention', '/landingpage/intention/mobile'], ['/landingpage/coscoShipping', '/landingpage/coscoShipping/mobile'] ] const useMobileAndPcBridging = () => { const router = useRouter() if (!process.browser) return const { pathname, query } = router const ITEM = PC_MOBILE_LIST.find((value) => value.includes(pathname)) if (!ITEM?.length) return const [PC_PATH, MOBILE_PATH] = ITEM if (window.device.mobile && MOBILE_PATH !== pathname) { router.push({ pathname: MOBILE_PATH, query }) return } if (!window.device.mobile && PC_PATH !== pathname) { router.push({ pathname: PC_PATH, query }) return } } export default useMobileAndPcBridging
中间件middleware.ts版本
middleware.ts
import { NextResponse } from 'next/server' import { type NextRequest } from 'next/server' import { equipment } from '@/utils' const PC_MOBILE_LIST = [ ['/landingpage/amazon', '/landingpage/amazon/mobile'], ['/landingpage/goOut', '/landingpage/goOut/mobile'], ['/landingpage/vppa', '/landingpage/vppa/mobile'], ['/gec/introduce', '/gec/introduce/mobile'], ['/greenCertificate/introduce', '/greenCertificate/introduce/mobile'], ['/landingpage/intention', '/landingpage/intention/mobile'], ['/landingpage/coscoShipping', '/landingpage/coscoShipping/mobile'] ] export function middleware(request: NextRequest) { const userAgent = request.headers.get('user-agent') || '' const { pathname, search } = request.nextUrl const device = equipment(userAgent) const ITEM = PC_MOBILE_LIST.find((value) => value.includes(pathname)) if (!ITEM?.length) return NextResponse.next() const [PC_PATH, MOBILE_PATH] = ITEM if (device.mobile && MOBILE_PATH !== pathname) { const path = new URL(MOBILE_PATH + search, request.url) console.log('移动端,跳转中...' + MOBILE_PATH) return NextResponse.redirect(path) } if (!device.mobile && PC_PATH !== pathname) { console.log('PC端,跳转中...' + PC_PATH) const path = new URL(PC_PATH + search, request.url) return NextResponse.redirect(path) } return NextResponse.next() } export const config = { matcher: [PC_MOBILE_LIST.flat(1)] }
上面代码中遇到了辅助函数判断设备 `equipment`,这里贴以下方法
utils/index.ts
export const equipment = function (userAgent?: string) { //判断终端 const u = userAgent || window.navigator.userAgent return { trident: u.indexOf('Trident') > -1, //IE内核 presto: u.indexOf('Presto') > -1, //opera内核 webKit: u.indexOf('AppleWebKit') > -1, //苹果、谷歌内核 gecko: u.indexOf('Gecko') > -1 && u.indexOf('KHTML') == -1, //火狐内核 mobile: !!u.match(/AppleWebKit.*Mobile.*/) || u.indexOf('Samsung') > -1, //是否为移动终端 ios: !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), //ios终端 android: u.indexOf('Android') > -1 || u.indexOf('Linux') > -1, //android终端或者uc浏览器 iPhone: u.indexOf('iPhone') > -1 || u.indexOf('Mac') > -1, //是否为iPhone或者安卓QQ浏览器 iPad: u.indexOf('iPad') > -1, //是否为iPad webApp: u.indexOf('Safari') == -1, //是否为web应用程序,没有头部与底部 weixin: u.indexOf('MicroMessenger') > -1 //是否为微信浏览器 } }
标签:丝滑,mobile,中间件,PATH,PC,indexOf,跳转,const,landingpage From: https://www.cnblogs.com/yz-blog/p/18284330