当前位置: 首页 > Web前端 > HTML

容易忽略的URL

时间:2023-04-02 14:06:38 HTML

众所周知vue-router有hash、html5、abstract三种模式。一般前端项目都会选择hash模式进行开发。最近做了一个基于vue-router开发的hash模式的操作活动。项目注册了两条路由(抽象Demo)varrouter=newVueRouter({routes:[{name:'index',path:'',component:indexcomponent},{name:'demo',path:'/demo',组件:演示组件}]});入口页面需要参数,所以提供网址:https://www.xxx.com?from=weixin,在浏览器中输入网址回车后,页面会自动添加一个#/改为https://www.xxx.com?from=weixin#/.单击索引页上的按钮可跳转到演示。同时,我想携带索引中获取的参数。看到API选择了如下方法,URL变成:https://www.xxx.com?from=weixin#/test?userId=123router.push({path:'demo',query:{plan:'private'}})生成查询URL的条件是什么?(跳转到上面的Demo页面后URL看起来怪怪的)vue-router是如何控制URL的?查询探索URL标准统一资源定位器(或统一资源定位器/定位地址、URL地址等,英文:UniformResourceLocator,常简称URL)标准格式:scheme:[//authority]path[?query][#fragment]==Example==下图显示了两个示例URI及其组件。分层部分┌──────────────────────────────────────────────────┐权限路径──────────────────┐┌────┴──────┐abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1└┬┘└──────────┬──────────┘└────┬──────┘└┬┘└──────────────────────────────────┘└──┬──┘scheme用户信息主机端口查询片段turn:example:mammal:monotreme:echidna└┬┘└─────────────────────────────────────────────────┘方案路径URL“?『『#』『?浏览器只识别url中的第一个“?”,后面会被当作参数“#”“#”一般用于页面内的定位,比如我们的锚点定位最熟悉。浏览器可以通过“onhashchange”监控哈希变化。HTTP请求中不包含#RequestHeadersReferer中不包含#Change#不会触发网页重新加载url中#后的任何字符将被截断。(http://www.xxx.com/?color=#fffrequestis:/color=)change#会改变historywindow.location.hashread#valueURLreadandoperateURLreadandoperate涉及location和history有两个objects,如下:locationAPI:attributehref=protocol+hostName+port+pathname+search+hashhostoriginmethodassignhrefreplace,notrecordhistoryreloadhistoryAPI:methodback()forward()go()H5newAPIpushState()replaceState()popstate监控变化Vue-router路由实现分析在初始化路由器时,根据指定的模式选择路由实现。当然,模式判断是有一定的逻辑和兼容策略的options.base,this.fallback)breakcase'abstract':this.history=newAbstractHistory(this,options.base)breakdefault:if(process.env.NODE_ENV!=='production'){assert(false,`invalidmode:${mode}`)}}我们选择hash模式进行深入分析,对应HashHistory模块,是history/hash.js实现的,调用时监听全局路由变化window.addEventListener(supportsPushState?'popstate':'有hchange',()=>{...})同时hash.js也实现了对push等API方法的封装。我们以推送为例。根据源码可以看出其实现是基于基类transitionTo的实现,如下:=thisthis.transitionTo(location,route=>{pushHash(route.fullPath)handleScroll(this.router,route,fromRoute,false)onComplete&&onComplete(route)},onAbort)}既然调用了transitionTo,那么我们看看它执行。获取参数后,调用confirmTransitiontransitionTo(location:RawLocation,onComplete?:Function,onAbort?:Function){//获取URL中的参数constroute=this.router.match(location,this.current)this.confirmTransition(route,()=>{this.updateRoute(route)onComplete&&onComplete(route)this.ensureURL()...})}同时在confirmTransition中实现了一个队列,顺序执行。迭代器通过后执行next,然后实现智信pushHash()改变页面的hash,最终实现${base}#${path}getUrl(path){consthref=window的连接函数.location.hrefconsti=href.indexOf('#')constbase=i>=0吗?href.slice(0,i):hrefreturn`${base}#${path}`}functionpushHash(path){if(supportsPushState){pushState(getUrl(path))}else{window.location.hash=path}}问题解决https://www.xxx.com?from=weixin#/test?userId=123这个页面看起来很奇怪,因为这个连接包含了几乎所有的参数,并且hash中有一个问号。不常见的一个URL中有多个问号的vue-router也是基于基本的URL操作来切换URL。在基础上,它封装了很多想法。还是应该多学习。比如实现的队列,继承的应用等等。总结标准的URL应该是search+hash。不要被现在的各种框架给骗了,误以为参数应该拼接在hash之后。URL中可以有多个问号,但是为了便于理解,尽量避免这种写法,避免上述尴尬问题的一种方法是HTML5Histroy模式。有兴趣的同学可以关注并实践了解其中的原理和设计模式。平时开发项目中可以参考参考文档https://github.com/vuejs/vue-...https://developer.mozilla.org...https://en.wikipedia.org/wiki...https://www.cnblogs.com/qingg...http://www.cnblogs.com/qinggu...https://segmentfault.com/p/12...https://segmentfault.com/a/11...