标签 web 下的文章

这篇文章个人觉得很受用,故仔细翻译了一下,有些地方可能翻译的不好,请见谅!

翻译后发现貌似已经有人翻译过,但是翻译的水平就有点。。。。。那篇文章中不仅忽略了知识点,并且出现了明显的语义和语法错误,有一定的误导作用,所以请务必重新阅读老高的翻译。文章中容易出错的地方老高已经注释(在文章中以【】标出)。

如需转载,请注明出处!

web开发者在发布你的作品前需要考虑的技术细节 What technical details should a programmer of a web application consider before making the site public!

原文地址: 来自stackexchange.com quora的回答

界面和用户体验

  • 要意识到浏览器的实现标准不一,请确保你的网站在主流浏览器中的正常展现。至少要针对一个最新的Gecko引擎(火狐)的浏览器、一个基于Webkit引擎(Safari或者其他移动端)的浏览器、Chrome、你想要支持的IE浏览器(可以借助IE应用程序兼容性VPC镜像)和Opera浏览器。同时需要考虑到在不同的操作系统下浏览器是如何渲染你的网站
  • 需要考虑来自其他浏览器的用户如何使用你的网站:智能手机、屏幕朗读器和搜索引擎,举个例子。--一些易用性信息:网页易读性倡议(WAI)和网站508规范(Section508),移动站开发:移动互联网开发者论坛(MobiForge)。
  • 构架:如果在不影响用户的情况下部署升级。有一个或者多个用来更改架构、代码或者内容更新的可用测试或运行环境,确保他们部署的可控性,以防止造成破坏。有一个自动化部署方案,用来提交更改到生产环境。最优的解决方案是结合使用一个版本控制系统(CVS, Subversion等【译者注:为啥没GIT】)或一个自动构造机制(Ant,NAnt等)。
  • 不要直接给用户展现不友好的错误信息。
  • 不要用纯文本的形式呈现用户的Email,否则他们会被垃圾邮件骚扰。
  • 给用户生成的链接加上rel="nofollow"属性,以避免SEO作弊
  • 为你的站点建立合理的限制机制,这一条同时属于安全细则。
  • 理解什么是渐进增强(progressive enhancement)【译者注:与之相对的是优雅降级(graceful degradation)】。
  • 如果一个请求提交成功,请重定向至其他地方,防止用户的重复提交。
  • 不要忘了考虑无障碍阅读,这对网站的优化来讲是一个好主意,而且有些情况下他是法律强制必须有的。 无障碍网页应用(WAI-ARIA)和Web内容无障碍指南2(WCAG 2)在这方面可以帮到你!
  • 不要让用户思考该如何操作

安全

性能

  • 必要时使用缓存,理解并使用HTTP缓存技术HTML5的Manifest技术
  • 图片优化 - 不要使用一个20KB大小的的图片最为重复背景。
  • 学习如何使用gzip压缩内容
  • 合并/链接多个样式表或多个脚本文件以减少浏览器的请求数,并且使用gzip压缩文件中重复的内容。
  • 看一看雅虎高性能站点,有很多不错的点子,包括提高前端性能和他们的YSlow工具(需求使用Firefox、Safira、Chrome、或Opera浏览器)。同时,Google page speed使用浏览器插件)也是一个不错的性能调校工具,他同时也会优化你的图片。
  • 针对小并且相关的图片使用CSS image sprite技术
  • 访问量大的站点需要考虑将不用内容分至不同的域名下。
  • 静态内容(如图片、css、js脚本还有不需要cookie的普通内容)应该被分配到一个不使用cookie的域名下,因为一个域名下的所有cookie和子域下的cookie将会被包含在所有对应的域名下。一个好的主意是使用CND加速,但是考虑到CND可能会挂,到时候本地的拷贝也会提供服务。
  • 最小化一个浏览器需要渲染一个页面所需要的请求数。
  • 利用工具Google Closure Compiler最小化你的js文件,还有其他的最小化工具
  • 确保有一个favicon.ico在服务器的根目录,就算html里没有提到他,浏览器也会自动请求他。如果你没有一个favicon.ico,那么会导致很多的404错误,并浪费带宽。

SEO

  • 使用搜索引擎友好的URL,如使用www.phpgao.com/technical_details.html,而不用www.phpgao.com/index.php?p=XXX
  • 将你的#变为#!,然后再服务端使用$_REQUEST["escaped_fragment"]接收google机器人发来的请求,换句话说,google会把./#!page=1变为?_escaped_fragments_=page=1。同时,针对使用火狐beta4或者Chrome浏览器的用户,使用history.pushState({"foo":"bar"}, "About", "./?page=1");,是一个不错的选择。这样的话即使浏览器的地址栏有变化,但是页面不会重新加载。这样就允许你使用?代替#以保留动态内容,同时告诉服务器当你通过邮件发送的链接到底是什么页面,同时 ajax不需要额外的请求。【这一段如果看不懂:请参考URL的井号
  • 不要给你的链接添加诸如**点我**的说明。这样做是在浪费SEO优化的机会,同时让读者不容易理解。
  • 需要提供一个XML网站地图,最好使用默认的地址/sitemap.xml
  • 当你有多个URL指向相同的页面,请使用[指出你需要强调的页面,这个问题可以在Google Webmaster Tools被找到。
  • 使用谷歌站长工具Bing站长工具
  • 一开始就是用Google分析(或者一个开源分析工具,例如Piwik)。
  • 了解robots.txt和搜索引擎爬虫的工作机制。
  • 在(www.phpgao.com)或(phpgao.com)之间选择一个,然后使用301重定向将域名重定向到主域名,以防止分权。【博主选用了带www的域名www.phpgao.com,所以访问不带www的域名phpgao.com会被301重定向】
  • 要知道有一些不守规矩的爬虫。
  • 如果你有一些非文本的内容,可以借助Google's sitemap extensions for video 等工具。

技术

  • 理解HTTP,诸如GET,POST,sessions,cookies还有“无状态”的含义。
  • 使用符合W3C规则的XHTML/HTML + CSS页面并确保他们通过验证。此行的目的是避免出现浏览器的怪异模式,同时作为一个奖励,它会更加兼容非传统的浏览器,如屏幕朗读器和手机设备。
  • 理解js在浏览器中如何工作【dom原型】。
  • 理解js、样式表和其他资源如何被载入并解析为一个页面并考虑他们对渲染性能的影响。除非你在分析应用或者使用html5-shims做测试,否则把你的脚本放在html的最后是一个不错的选择。
  • 理解js的沙盒的工作机制,尤其是你在使用iframes的时候。
  • 意识到js是可以被禁用的,而Ajax也仅仅是一个扩展功能,而不是基准功能。尽管大部分用户多ajax置之不顾,但是要记住无脚本已经越来越流行,移动设备也可能不会像你期待的那样运行,并且Google在索引你的站点时几乎不会运行你的JS脚本。
  • 了解301和302重定向的区别(这也是一个SEO论题)
  • 尽可能的掌握你的产品部署平台。
  • 考虑使用样式表重置或者normalize.css.
  • 考虑js框架(jQueryMooToolsPrototypeDojoYUI 3),他们会屏蔽很多不同浏览器使用JS操作DOM的差异。【简化操作,屏蔽差异】
  • 同时考虑到渲染性能和js框架,建议使用诸如Google Libraries API的公共服务库载入框架,好处是浏览器在已经缓存的情况下不需要在从网站下载。【如果每个网站都是用公共库,命中率将大大提高】
  • 不要重复造轮子。再做任何事情之前先google之,看看有没有合适的组建或者已经实现的例子。有99%的几率你需要的功能已经被实现并开源。
  • 另一个方面,在你最终决定需求之前,不要一开始就上很多个库。尤其是针对客户端,最重要的是轻量、快速和灵活。

Bug修复

  • 你必须知道这个事实,纵观整个软件周期,你将花费20%的时间写代码,剩下80%的时间都在维护他,所以好好码吧!
  • 建立一个良好的错误报告解决方案。
  • 有一个客户反馈系统。
  • 将应用的工作原理写成文档,以便作为将来支持和运维的参考。
  • 有计划行的备份你的站点!(同时确保他们是可恢复的备份)Ed Lucas的回答中包含了一些建议。建立一个恢复机制,而不是备份机制。
  • 使用版本控制系统保存你的文件,如SubversionMercurialGit.
  • 不要忘了做验收检测。Selenium可以帮你的忙。
  • 确保你有足够的空间保存log4j, log4netlog4r生产的日志。如果你的生产环境出错,你可以用日志找到问题的根源。
  • 记录日志时请确保你同时记录了可处理和不可处理的错误。汇报/分析日志,他将会告诉你系统哪里出了问题。

搜PHP长链接把这个搜出来了,2006年的帖子比较久远了,希望对你有帮助!

转自http://bbs.phpchina.com/forum.php?mod=viewthread&tid=4577&page=1 中forest的回帖:

永久的数据库连接是指在脚本结束运行时不关闭的连接。当收到一个永久连接的请求时。PHP 将检查是否已经存在一个(前面已经开启的)相同的永久连接。如果存在,将直接使用这个连接;如果不存在,则建立一个新的连接。所谓“相同”的连接是指用相同的用户名和密码到相同主机的连接。

对 web 服务器的工作和分布负载没有完全理解的读者可能会错误地理解永久连接的作用。特别的,永久连接不会在相同的连接上提供建立“用户会话”的能力,也不提供有效建立事务的能力。实际上,从严格意义上来讲,永久连接不会提供任何非永久连接无法提供的特殊功能。

为什么?

这和 web 服务器工作的方式有关。web 服务器可以用三种方法来利用 PHP 生成 web 页面。

第一种方法是将 PHP 用作一个“外壳”。以这种方法运行,PHP 会为向 web 服务器提出的每个 PHP 页面请求生成并结束一个 PHP 解释器线程。由于该线程会随每个请求的结束而结束,因此任何在这个线程中利用的任何资源(例如指向 SQL 数据库服务器的连接)都会随线程的结束而关闭。在这种情况下,使用永久连接不会获得任何地改变――因为它们根本不是永久的。

第二,也是最常用的方法,是把 PHP 用作多进程 web 服务器的一个模块,这种方法目前只适用于 Apache。对于一个多进程的服务器,其典型特征是有一个父进程和一组子进程协调运行,其中实际生成 web 页面的是子进程。每当客户端向父进程提出请求时,该请求会被传递给还没有被其它的客户端请求占用的子进程。这也就是说当相同的客户端第二次向服务端提出请求时,它将有可能被一个不同的子进程来处理。在开启了一个永久连接后,所有请求 SQL 服务的后继页面都能够重新使用这个已经建立的 SQL Server 连接。

最后一种方法是将 PHP 用作多线程 web 服务器的一个插件。目前 PHP 4 已经支持 ISAPI、WSAPI 和 NSAPI(在 Windows 环境下),这些使得 PHP 可以被用作诸如 Netscape FastTrack (iPlanet)、Microsoft’s Internet Information Server (IIS) 和 O’Reilly’s WebSite Pro 等多线程 web 服务器的插件。永久连接的行为和前面所描述的多过程模型在本质上是相同的。注意 PHP 3 不支持 SAPI。

如果永久连接并没有任何附加的功能,那么使用它有什么好处?

答案非常简单――效率。当客户端对 SQL 服务器的连接请求非常频繁时,永久连接将更加高效。连接请求频繁的标准取决于很多因素。例如,数据库的种类,数据库服务和 web 服务是否在同一台服务器上,SQL 服务器如何加载负载等。但我们至少知道,当连接请求很频繁时,永久连接将显著的提高效率。它使得每个子进程在其生命周期中只做一次连接操作,而非每次在处理一个页面时都要向 SQL 服务器提出连接请求。这也就是说,每个子进程将对服务器建立各自独立的永久连接。例如,如果有 20 个不同的子进程运行某脚本建立了永久的 SQL 服务器永久连接,那么实际上向该 SQL 服务器建立了 20 个不同的永久连接,每个进程占有一个。

注意,如果永久连接的子进程数目超过了设定的数据库连接数限制,系统将会产生一些缺陷。如果数据库的同时连接数限制为 16,而在繁忙会话的情况下,有 17 个线程试图连接,那么有一个线程将无法连接。如果这个时候,在脚本中出现了使得连接无法关闭的错误(例如无限循环),则该数据库的 16 个连接将迅速地受到影响。请查阅使用的数据库的文档,以获取关于如何处理已放弃的及闲置的连接的方法。 警告

在使用永久连接时还有一些特别的问题需要注意。例如在永久连接中使用数据表锁时,如果脚本不管什么原因无法释放该数据表锁,其随后使用相同连接的脚本将会被永久的阻塞,使得需要重新启动 httpd 服务或者数据库服务。另外,在使用事务处理时,如果脚本在事务阻塞产生前结束,则该阻塞也会影响到使用相同连接的下一个脚本。不管在什么情况下,都可以通过使用 register_shutdown_function() 函数来注册一个简单的清理函数来打开数据表锁,或者回滚事务。或者更好的处理方法,是不在使用数据表锁或者事务处理的脚本中使用永久连接,这可以从根本上解决这个问题(当然还可以在其它地方使用永久连接)。

简单的记录一下搭建自己的博客需要做的事情!

确定主题

一个网站的主题很重要,要不然你会无从下手,所以千万不要像我这样开一个这么无聊的blog。为什么说此步骤最难,就是因为点子是最重要的,只要主题(目标)明确,那么建立(实现)它就是易如反掌了。

选域名

域名是什么?其实就是一个网站的艺名而已。人家的网站叫“234.156.78.90”,你的叫“ccav.com”,那么你说那个更容易出名呢?所以,好的域名可能让你的网站迅速火起来。举个小栗子,以前的京东商城的域名是360buy.com,不懂英语的人当然不好记了,现在改名jd.com,既好记又提升了企业形象,何乐而不为呢?(估计这个域名京东花了不少钱)。不建议大家购买com以外的域名,尤其是cn结尾的,至于为什么大家可以自己研究。域名选好了后,就购买空间了。

虚拟主机(网站空间)

光是有了像phpgao.com这样的域名是不够的,因为你需要把你的文章放到互联网上供大家访问,所以你需要一个专用服务器,当然自己搭建服务器也是可以的,但是如果是个规模不大的网站老高建议还是租用吧,我的空间就是淘宝上买的,28半年,香港主机,速度还行。(为什么是香港空间?免备案呗!)

域名与空间的绑定

GOOD!既然你已经有了域名和空间,是时候将它们相互关联了。这一步比较关键!为了让大家更好的理解这一节。老高来举个大栗子,某一天老高要孤身一人拜访位从未谋面的远房亲戚,远程通话后确定目的地,坐飞机2小时(想的好美啊),下飞机后找那个举着牌子的人,我才能顺利见到那位亲戚。也就是说,我从出发到坐飞机,到达后根据牌子辨认身份这一系列的动作如果有一个失误,我的此次出行就是失败的,之后我只能沮丧的回家了。。。反应到现实就是:和我通话的那个人就是域名,他告诉我他在哪个IP等我,等我通过IP到站后,找那个举着牌子的人,这样就完成了一次“见面”。简单的说空间有个IP,你的域名必须解析到那个IP才行,当然不要忘了空间需要和你的域名绑定。

最后的工作

如果域名没有备案的话,那么你的空间应该和我一样不在内地吧。不过不要紧,能访问就行。想要搭建WP这类博客,你的空间还需要一个不是太小的MYSQL空间,也就是传说中的数据库。我的空间是200M+200M型,也就是说我的空间能放小于200M的MP3文件并且在数据库能够存放200M的数据。其实这么点空间建一个站已经很富裕了。(注:国外的空间不是很稳定,一定要定期备份!)

有些网站真是可恶,把右键屏蔽了不给复制,这样还不行(因为可以使用快捷键CTRL+C复制) 他们竟然不让我们选择文字。。。这样下来我们既不能复制,连源代码都不能看了。是可忍孰不可忍,既然这样,那我就不客气了!

找到病根是关键

原来是JS捣的鬼

纯html是无法实现屏蔽右键等功能的,所以很简单就能想到是js的问题,那么我们就找找到底是那些代码段使得我们无法使用邮件功能呢? 既然右键被禁止了,那我们如何才能看到网页的源代码呢? 其实很简单,PHP@老高建议你使用chrome浏览器打开你想要破解的网站,使用快捷键CTRL+U即可轻易查看网页的源代码!怎么样,很简单吧? 好了既然我们已经找到源代码,那就开始找那个害人的代码段吧!

代码一 这个是比较难找的代码,一般隐藏在网页的头部或者藏在某些引用的js文件中


代码二

这个比较容易找到,直接找到标签,之后就是此句,与代码一异曲同工


解决方法

IE浏览器 使用IE的童鞋可以试试在浏览器的地址栏输入

javascript:alert(document.oncontextmenu=document.onselectstart="OK")

或者

javascript:alert(document.body.oncontextmenu=document.body.onselectstart="OK")

之后弹出对话框,点击确认即可!现在点击右键或者选择文字试试,是不是已经被破解了? 请注意!该方法可能已经失效,因为新一代浏览器对安全性有了很大的提高,所以在地址栏输入脚本可能会被禁止!

接下来就是将他删除掉即可: 在代码上点击右键:选择第二项Edit Attribute,将其属性删除,结果代码变成这样: 不用怀疑了,刚才限制的功能已经恢复啦!

其他浏览器

以chrome为例 首先,在被屏蔽的网站上点击F12,出现了如下图所示代码(注:老高@PHPer使用的是chrome v30,不同版本的界面留有不同)

当然,您的火眼金睛可能立即发现了蓝色标记的一行代码


接下来就是将他删除掉即可:

在代码上点击右键:选择第二项Edit Attribute,将其属性删除,不用怀疑了,限制的功能已经恢复啦!

终极方法

在浏览器中将以下代码存为书签,名为解锁,在被禁网址中点击一下解锁,即可解开~

javascript:(function() { function R(a){ona = "on"+a; if(window.addEventListener) window.addEventListener(a, function (e) { for(var n=e.originalTarget; n; n=n.parentNode) n[ona]=null; }, true); window[ona]=null; document[ona]=null; if(document.body) document.body[ona]=null; } R("contextmenu"); R("click"); R("mousedown"); R("mouseup"); R("selectstart");})()