URL的设计
URL的设计是一个很复杂的问题,我不能说有什么“正确”的解决方案——其挺类似于其他方面的设计的,有好的URL设计,有糟糕的URL设计,在这两者之间的情况也个个不同——它是主观的。不过这并不意味着不存在用于创建出非常好的URL的最佳做法。我希望我这些年来学到的一些URL设计的最佳做法能够给你留下深刻的印象,并且我会解释为什么我认为使用新的HTML5 javascript的history API来工作是一件很令人兴奋的事情。
你应该花一些时间来设计一下你的URL地址结构。
在读完本文之后,如果有一件事情是我希望你记住的话,那就是花一些时间来设计你的URL地址的结构。不要把它留给你的框架来决定,不要听天由命,依赖运气。要仔细地考虑,认真摸索出一种经验。 URL的设计是一个很复杂的问题,我不能说有什么“正确”的解决方案——其挺类似于其他方面的设计的,有好的URL设计,有糟糕的URL设计,在这两者之间的情况也个个不同——它是主观的。 不过这并不意味着不存在用于创建出非常好的URL的最佳做法。我希望我这些年来学到的一些URL设计的最佳做法能够给你留下深刻的印象,并且我会解释为什么我认为使用新的HTML5 javascript的history API来工作是一件很令人兴奋的事情。
为什么需要对你的URL进行一番设计
URL栏已经成为了现代浏览器的一个主要吸引人的地方了,且它再也不仅是一个URL栏那么简单——你可以输入部分的URL,然后浏览器就像是会使用黑魔法似的召唤出了你正要查找的确切的完整地址。当我在我的URL栏中输入了resque issues时,得到的第一个结果是https://github.com/defunkt/resque/issues。 URL是全球统一的,它们可用在Chrome、Safari、Internet Explorer、cURL、wget、你的iPhone、Android上,甚至会被写在便签上。它们就是web网络的一种全球通用的语法。但是不要把这看成是理所当然的。 任何一个定期访问你的网站的半技术化的用户都应该能够基于内存中的URL结构来浏览你的应用的90%部分。为了能够实现这一点,你的URL必需是要注重实用性的,就几乎仿佛它们就是数学方程式一样——许多简单的规则组合成一种策略性的方式,以此来获得他们想要的页面。
顶层的部分是最为重要的
URL最有价值的方面在于其顶层的部分。在我看来,在想法形成了之后,这就是接下来的任何启动都应该最先要讨论的事情,要远在任何的技术讨论之前,要远在任何的代码编写之前。这一顶层部分将会改变形成你的网站功能的基础。 我是不是有些夸张了?看起来可能会是这样——但是以后会有1,000,000 个用户,想想它会带来多大的影响。想一下Facebook推出用户名是多么重大的一件事。可用的URL就像是不动产,而顶层的部分就是体现在外面的最好的资产。 另一个快速提示——每当你构建一个新的站点时,考虑一下这一组不实用的URL的黑名单列表(或许可从Quora的URL中了解到一点糟糕的URL设计)
命名空间是一种很棒的扩展URL的工具
命名空间可以作为一种很棒的建立实用的URL结构的方式,这种结构在后续的使用中很容易被记住。我在这里说的命名空间指的是什么?我的意思是,URL中指明了不同内容的那部分。一个例子: https://github.com/defunkt/resque/issues 在上面的URL中,defunkt/resque 就是命名空间。为什么这会有用?这是因为在这一个URL之后的任何部分都突然变成了一个新的顶层部分,因此你可以去到任何的一个《user》/《repo》 , 然后加上/issues或者可能是/wiki,取得相同的页面,但是是在不同的命名空间下。 保持命名空间的清晰,不要一开始就把一些内容放在/feature/《user》/《repo》下,一些放在/《user》/《repo》/feature下。对于命名空间来说,要发挥效用就必须是统一的。
查询串是很棒的过滤和排序的手段
关于查询串web有着一个混乱的过去,我见过各式各样的事情,从每个网页都使用同一个URL加上不同的查询参数的网站,到一个查询串参数都不用的网站,各种情况都有。 我喜欢把查询串想象成URL的旋钮——其调整你的当前视图,把它按照你的喜好来进行微调,这就是为什么它们用在排序和过滤这些行为上会如此之棒。坚持一种统一的模式(比如说sort=alpha&dir=desc ),你就会把通过URL栏进行的排序和过滤变得简单易记。 关于查询串还有最后一件事情:在没有附加查询串的情况下,页面应该是有效的,其可能给出的是一个不同的页面,但没有查询串的URL应该是要呈现出页面的。
英文网站的非ASCII URL是很糟糕的
这个世界是一个复杂的地方,充满着¿ümlåts?, ¡êñyés!和各种令人畏惧的字符☄。这些字符在任何英文网站的URL中都是不会有一席之地的。使用英文的键盘输入这些字符很复杂,很多时候延展成浏览器中的一些混乱的字符(有在url中见过xn--n3h吗?这是一个☃)。
URL是为人设计的——而非为搜索引擎设计的
我是在这一行业中成长起来,学会了如何玩搜索引擎(好吧,就是Google)的把戏,以此来从我的联盟营销中赚钱。因此关键词堆砌URL的做法对我来说并不陌生。像下面这样来来结束一个URL的情况相当常见: http://guitars.example.com/best-guitars/cheap-guitars/popular-guitar 就SEO的目的来说,使用这种URL的效果会很好,幸运的是,2003年Google的飓风式的更新消除了这类URL的任何排名优势。遗憾的是,专业的SEO行业被强取豪夺给围绕着,因此其可能还会建议你使用许多你尽可能想得到的关键字来堆砌你的URL 记住另外的一些要点: 1. 下划线只有一个糟字可言,坚持使用破折号。 2. 使用短的、完整的并且是大家都知道的单词。如果某个部分中有一个破折号或是一个特殊的字符的话,这个词就有可能太长。 URL是提供给人用的,为使用的人设计它们。
URL是一种协议
URL是一种协议,在一个可预见的位置尽可能长久地供应某些东西。一旦你的首个访问者点击了URL,那么你就隐式地进入了这样的一种协议中,即如果他们记住了来过该页面或是点击了刷新按钮话,那么他要看到相同的东西。 在已经向公众推出之后就不要再改变你的URL,如果你绝对有必要改变你的URL的话,加上重定向——这不那么会引起惊慌。
任何事物都应该有一个URL
在一个理想的环境中,你的网站上的任何一个单独的屏幕显示都应该得出一个URL,这一URL可被拷贝和粘贴来在另一个选项卡或是浏览器中再次产生相同的屏幕内容。公平地说,这并不是完全有可能的。除非是新近使用了一些新的HTML5浏览器的history Javascript API。值得注意的是,有两个新的方法: onReplaceState — 该方法代替了浏览器历史中的当前URL,并让后退(back)按钮不受影响。 onPushState – 该方法把一个新的URL压入到浏览器的历史中,代替URL栏中的URL,并把它加入到浏览器的历史栈中(影响到后退按钮)。 何时使用onReplaceState 以及何时使用onPushState 这些新方法允许我们改变URL栏中的整个路径,而不仅是锚元素。随着这一新的强大功能而来的是一种新的设计责任——我们需要摸索出后退按钮的使用经验。 为了确定使用哪一个方法,问你自己这样的一个问题:这一行为产生了新的内容呢?抑或是相同内容的不同显示?
1. 产生了新的内容——你应该使用onPushState(例如:分页链接)
2. 产生了相同内容的不同显示——你应该使用onReplaceState(例如:排序和过滤)
使用你自己的判断,不过这两个规则应该会符合你80%的情况。考虑一下,当你点击后退按钮时,你希望看见什么,然后做到你所希望的。 链接的行为就应该像一个链接 诸如《a》和《button》之类的链接元素有着许多很棒的内建功能。如果你中键点击或是命令点击它们的话,它们会打开一个新的窗口。当你悬停在其之上时,你的浏览器会在状态栏中告诉你它的URL地址。在用到onReplaceState和onPushState时,不要破坏了这一行为。
1. 把AJAX请求的位置嵌放在锚元素的href属性中。
2. 在人们中键点击或是命令点击它们时,从Javascript的点击处理程序中返回true值。 这是一个相当简单的做法,在你的单击处理程序内部使用一个快速的条件判断。下面是一个jQuery兼容的例子片段:
$('a.ajaxylink').click(function(e){ // API 浏览器不支持history API的后备 if (!('replaceState' in window.history)) return true // 确保是中键的、控制的和命令的正常点击行为 if (e.which == 2 || e.metaKey || e.ctrlKey){ return true } // 做一些很棒的事情,然后改变URL window.history.replaceState(null, "New Title", '/some/cool/url') return false })
特定于POST行为的URL需要废除
在过去,开发社区很爱创建一些不能被再次使用的URL,我喜欢把它们称为特定于POST行为(POST-specific)的URL——这是一些会在你提交了一个表单之后出现在你的地址栏中的URL,但是当你尝试着拷贝和粘贴这些url到新的选项卡中时,你就会得到一个错误的地址。 这类UR完全没有存在的借口,特定于Post行为的URL是用于重定向和API的——而非给最终用户的。
一个很棒的例子
Example URL 1. 用户生成的URL部分只用ASCII字符(defunkt、resque)。 2. “pull”是“pull request”的简短版本——单个单词,很容易关联到来源词。 3. 拉请求(pull request)号局限的范围为defunkt/resque (此处是从1开始)。 4. 锚指向一个滚动位置,内容不会被挡住。 知识点精萃:URL还有许多不同的格式——找出patch和diff的版本看看。
一个时代的开始
我希望随着新的Javascript API的使用的增多,设计者和开发者会花一些时间来设计一下URL。这对于任何网站的可用性来说都是一个很重要的部分,但我却见到太多忽略了这一点的URL了。尽管重新设计网站的外观和感觉很容易,但重新设计URL的结构却要难得多。 但我也很激动,这些年来我有观察到URL的改变。有时是硬链接被牺牲在了AJAX这一祭坛上,有时是牺牲性能来为用户生成真实的URL。最终我们会来到这样的一个时间点上,到那时,我们既可以得到部分页面渲染的性能和可用性优势,同时又获得设计有条理的和精炼的URL的经验。