{"action":"opened","issue":{"url":"https://api.github.com/repos/thx/magix/issues/12","repository_url":"https://api.github.com/repos/thx/magix","labels_url":"https://api.github.com/repos/thx/magix/issues/12/labels{/name}","comments_url":"https://api.github.com/repos/thx/magix/issues/12/comments","events_url":"https://api.github.com/repos/thx/magix/issues/12/events","html_url":"https://github.com/thx/magix/issues/12","id":168459593,"number":12,"title":"magix中的url解析与处理","user":{"login":"xinglie","id":1290017,"avatar_url":"https://avatars.githubusercontent.com/u/1290017?v=3","gravatar_id":"","url":"https://api.github.com/users/xinglie","html_url":"https://github.com/xinglie","followers_url":"https://api.github.com/users/xinglie/followers","following_url":"https://api.github.com/users/xinglie/following{/other_user}","gists_url":"https://api.github.com/users/xinglie/gists{/gist_id}","starred_url":"https://api.github.com/users/xinglie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/xinglie/subscriptions","organizations_url":"https://api.github.com/users/xinglie/orgs","repos_url":"https://api.github.com/users/xinglie/repos","events_url":"https://api.github.com/users/xinglie/events{/privacy}","received_events_url":"https://api.github.com/users/xinglie/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2016-07-30T09:48:29Z","updated_at":"2016-07-30T09:48:29Z","closed_at":null,"body":"传统的URL处理：\r\n\r\n    考虑这样的URL：http://etao.com/list?page=2\r\n    切换到下面的URL：http://etao.com/details?itemId=200089\r\n\r\n直接修改URL页面肯定刷新，如果做到不刷新就只有使用hash的形式或pushState，如上述的URL切换，使用hash后会变成这样：\r\n\r\n    http://etao.com/list?page=2#!/details?itemId=20089\r\n\r\n(关于hash中的叹号可搜索hashbang获取更多内容)\r\n\r\n那对于上述的URL Magix中是如何处理的？\r\n\r\n    query中的path与参数为/list?page=2\r\n    hash中的path与参数为 /details?itemId=20089\r\n\r\nMagix解析出来的对象是这样的：\r\n\r\n```\r\n{\r\n    query:{\r\n        path:'/list',\r\n        params:{\r\n            page:'2'\r\n        }\r\n    },\r\n    hash:{\r\n        path:'/details',\r\n        params:{\r\n            itemId:'20089'\r\n        }\r\n    },\r\n    path:'/details',\r\n    params:{\r\n        page:'2',\r\n        itemId:'20089'\r\n    }\r\n}\r\n```\r\n\r\n可以看出query与hash各自解析，然后把query与hash合并后再给出path与params\r\n\r\n合并后的path是采用hash中的，因为当hash有值时，应当以hash中的值为准，那如果页面进入时没有hash,如最开始的：\r\n\r\n    http://etao.com/list?page=2\r\n\r\n这个url的path如何确定？\r\n\r\n这个时候需要看Magix.config中是如何配置的：\r\n\r\n```\r\nMagix.config({\r\n  //…\r\n  defaultPath:'/home'\r\n});\r\n```\r\n\r\n取决于defaultPath如何配置。那么上述URL解析出来的对象就是：\r\n\r\n```\r\n{\r\n    query:{\r\n        path:'/list',\r\n        params:{\r\n            page:'2'\r\n        }\r\n    },\r\n    hash:{\r\n        path:'',\r\n        params:{\r\n\r\n        }\r\n    },\r\n    path:'/home',\r\n    params:{\r\n        page:'2'\r\n    }\r\n}\r\n```\r\n如果未配置defaultPath呢？如果未配置则使用空字符串。\r\n\r\n所以在使用hash做为保存页面状态URL时，忽略query中的path，统一使用hash中的path\r\n\r\n那相同参数时如何处理？如：\r\n\r\n    http://etao.com/list?page=2#!/list?page=3\r\n\r\n这时候会把hash中的参数merge到query中，合并出来的即是最终的。相同参数则覆盖。最终解析的结果为：\r\n\r\n```\r\n{\r\n    query:{\r\n        path:'/list',\r\n        params:{\r\n            page:'2'\r\n        }\r\n    },\r\n    hash:{\r\n        path:'/list',\r\n        params:{\r\n            page:'3'\r\n        }\r\n    },\r\n    path:'/list',\r\n    params:{\r\n        page:'3'\r\n    }\r\n}\r\n```\r\n\r\n以上是传统URL的处理，HTML5新加入了history.pushState相关的API，可以更友好的改变URL而不刷新页面。如果使用该功能需要[启用edgerouter模块重新编译magix](https://github.com/thx/magix/issues/10)\r\n\r\n启用该功能后，在支持HTML5 API的浏览器上，如URL的切换\r\n\r\n    从：http://etao.com/list?page=2\r\n    切换到：http://etao.com/details?itemId=20089\r\n    最终变成：http://etao.com/details?itemId=20089\r\n\r\n不使用hash，直接改变\r\n\r\n    在不支持HMLT5的浏览器上，URL的切换\r\n\r\n    从：http://etao.com/list?page=2\r\n    切换到：http://etao.com/details?itemId=20089\r\n    最终变成：http://etao.com/list?page=2#!/details?itemId=20089\r\n\r\n使用hash来保存url的变化\r\n\r\n那么这时候的解析结果是如何的，尤其是path如何确定？\r\n\r\n解析结果首先确定url中是否存在hash，如果存在hash则优先使用hash中的path。(为什么要优先使用hash中的？假设从不支持HTML5的浏览器上拷贝URL，则很有可能带有hash部分，粘贴到不管是支持HTML5还是不支持HTML5的浏览器上，都需要使用hash中的path,因为hash中的才是正确的)\r\n\r\n如果没有hash则使用query中的path，对于参数更容易处理，如果存在hash，则把hash中的merge到query中，同名覆盖即可，原因同上。\r\n\r\n\r\n以上就是hash和html5之间的解析差异，接下来再说一些使用上的细节\r\n\r\n假设初始url是这样的：\r\n\r\n    http://etao.com/list?page=20&rows=30\r\n\r\n使用Magix.Router的to方法进行导航：\r\n\r\n    Router.to(‘/list?page=1’);\r\n\r\n假设我们使用pushState，并且当前浏览器支持，于是url会变成：\r\n\r\n    http://etao.com/list?page=1;\r\n\r\npage参数改变，同时丢掉了rows参数，这是合理的\r\n\r\n当在不支持history state的浏览器上时，url会变成：\r\n\r\n    http://etao.com/list?page=20&rows=30#!/list?page=1&rows=;\r\n\r\n根据前面讲到的参数合并规则，虽然2种解析出来的结果并非严格一致，前者解析出来的参数为:`{page:1}`,后者为:`{page:1,rows:''}`，相对于原来的url解析出来的参数`{page:20,rows:30}`，都是改变了参数page和rows，这是没问题的\r\n\r\n只是从参数中取rows时，第1种是undefined，第2种是空字符串，严格来讲这是有问题的，不过在具体使用上并不会引入太大的问题(从地址栏中拿到的参数都是需要校验的)，所以暂忽略掉这个风险"}}
{"actor":{"display_login":"xinglie"}}