最近的译文距今已有4年之久,原文有一定的更新。今天踩着前辈们的肩膀,再次把这篇文章翻译整理下。一来让自己对web缓存的理解更深刻些,二来让大家注意力稍稍转移下,不要整天HTML5, 面试题啊叨啊叨的~~ 什么是Web缓存,为什么要使用它? Web缓存游走于服务器和客户端之间。这个服务器可能是源服务器(资源所驻留的服务器Add),数量可能是1个或多个;这个客户端也可能是1个或多个。Web缓存就在服务器-客户端之间搞监控,监控请求,并且把请求输出的内容(例如html页面、 图片和文件)(统称为副本)另存一份;然后,如果下一个请求是相同的URL,则直接请求保存的副本,而不是再次麻烦源服务器。 使用缓存的2个主要原因: 降低延迟:缓存离客户端更近,因此,从缓存请求内容比从源服务器所用时间更少,呈现速度更快,网站就显得更灵敏。 降低网络传输:副本被重复使用,大大降低了用户的带宽使用,其实也是一种变相的省钱(如果流量要付费的话),同时保证了带宽请求在一个低水平上,更容易维护了。 Web缓存的类型 1. 浏览器缓存在任何现代浏览器上(如IE, FireFox, Chrome)折腾清除隐私数据(//zxx: 原文说的是首选项,显然out了,这里有改动)的对话框,你很可能会注意到“缓存”这个设置项。 浏览器会在你的硬盘上专门开辟一个空间专门为你存储资源副本。浏览器缓存的工作规则很简单:检查以确保副本是最新的,通常只要一次会话(就是当前浏览器调用的这次N)。 浏览器缓存在用户触发“后退”操作或点击一个之前看过的链接的时候很管用。同样,如果你在网站上访问同一张图片,该图片可以从浏览器缓存中调出并几乎立即显现出来。 2. 代理服务器缓存Web代理服务器使用同样的缓存原理,只是规模更大。代理以同样的方式服务千万用户,大公司和ISP(Internet Server Provider, Internet服务提供商Add)经常在他们的防火墙或者单独的设备(也被称为中介(intermediaries))上架设代理缓存。 由于代理服务器缓存并非客户端或者源服务器的一部分,而是处于网络中,请求需要以某种方式路由到它们。一种方法是手动设置,告诉浏览器的你常用的代理服务器(//zxx: 翻墙的时候常用的),另外就是使用拦截。拦截代理(Interception proxies)把Web请求根据自己的底层网络重定向,因此,客户端无需配置,甚至都不需要知道它们。//zxx: 维基百科上提供的几种检测拦截代理服务器存在的方法add,您若有兴趣,可以点击这里查看。 代理缓存属于一种共享缓存;往往有大量的用户使用,因此,其在降低延时和网络流量上很有用,毕竟每个副本都被大量重用。//zxx: 这里我有疑问:就算是放在代理服务器上,每次获取还是要通过网络的啊,如何降低了网络流量呢?希望谁可以帮忙解惑下。 3. 网关缓存也被称为“反向代理缓存”或“替代缓存”。网关缓存同样是起中介作用的,不过不是(素不相识、不曾谋面的Add)网络管理员部署的,而多半是网站管理员(公司专门的运维工程师、或UED或程序组某人Add)他们自己部署,这样更容易扩展与维护。 可以有多种方法把请求路由到网关缓存,但通常使用某种形式的负载均衡器①,使它们中的一个或多个看起来像是源服务器。内容分发网络②(CDNs)为整个网络(或部分)分配网关缓存,然后把这些缓存卖给需要的网站。Speedera③和Akamai④就是代表性的网络内容发布商。 ①负载均衡器:是一种采用各种分配算法把网络请求分散到一个服务器集群中的可用服务器上去,通过管理进入的Web数据流量和增加有效的网络带宽,从而使网络访问者获得尽可能最佳的联网体验的硬件设备。 ②内容分发网络:即CDN, 基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快、更稳定。通过在网络各处放置节点服务器所构成的在现有的互 联网基础之上的一层智能虚拟网络,CDN系统能够实时地根据网络流量和各节点的连接、负载状况以及到用户的距离和响应时间等综合信息将用户的请求重新导向 离用户最近的服务节点上。其目的是使用户可就近取得所需内容,解决 Internet网络拥挤的状况,提高用户访问网站的响应速度。 ③Speedera:是一家全球性的内容服务提供商,它与北美、欧洲以及亚太地区的1000多家大型运营商都有联系,并为那些不想在自己服务器上寄存内容的公司提供软件下载、媒体及其它服务管理等业务。05年的时候被下面要介绍的Akamai以$130m的价格给收购了。 ④Akamai:美国Akamai是国际上最大的CDN服务商,它巨大的网络分发能力在峰值时可达到15Tbps。 Akamai公司是为数不多的旨在消除Internet瓶颈和提高下载速度的几家新公司之一,是一个致力于网络交通提速的”内容发布”公司,是波士顿高技 术区最卓越的新兴企业之一。Akamai公司向全球企业提供发送互联网内容,汇流媒体和应用程序的服务(目前,该公司为15个国家的企业管理着8000多 台服务器)。1998年,丹尼尔。L和麻省理工学院的一些研究人员一起创立了这家公司,他在麻省理工学院的硕士论文构成了Akamai公司最初的”自由 流”(Freeflow)技术的核心。 本教程重点在浏览器和代理缓存,尽管有些信息对网关缓存感兴趣的人也适用。 Web缓存无害吗?为什么要鼓励缓存? Web缓存是互联网中最容易被误解的技术之一。网站管理员特别希望知道网站的一举一动,比方说多少人访问啦,访问时间啊什么的,而缓存会“隐藏”他们的用户,他们就无从得知到底谁访问了这个站点。 捡了芝麻丢西瓜,自认为放弃缓存可以精确跟踪用户,实际上,互联网中有太多的变数,想精确得到一张用户查看网站的图片?没那么简单的,亲!如果你很重视这个问题,恭喜你,本文正好提供了解决之道,即保证缓存友好,同时又能获得统计。 另外需要注意的是,缓存的内容都是旧的过时的。因此,如何准确更新就成了一个问题。不过不要担心,本文会向你展示如何配置服务器,让缓存就像你的女仆——随便调教。 CDN算是个挺有意思的技术,不同于代理缓存,CDN的网关缓存和被缓存的Web站点的利益是一致的,因此,上面提到的问题对于CDN而言是没有的。不过,即使你使用了CDN,你仍要顾虑下游的代理和浏览器缓存。 以上为缓存可能的“糟粕”,那他好的地方呢?缓存可以让你的Web站点加载更快,让你的服务器和互联网链接间负担更小。这种差异会导致一些类似质的 变化,一个网站要几秒钟才能加载出来,而另外一个充分发挥缓存的优势,几乎瞬间显示。用户自然更喜欢那个加载迅速的站点,访问也更多。 再说个现实示例,许多大型互联网公司花费了数百万美元,在世界各地设立服务器集群来复制他们的内容,以使其尽可能快被他们的用户访问。缓存为你做同样的事情,而且他们更接近最终用户。最重要的是,你不要花银子。 实际上呢,无论你喜欢与否,代理和浏览器缓存都会被使用。如果你站点的缓存配置不正确,你只能听天由命了。 Web缓存如何工作 所以的缓存都有一套自己的规则,可以用来决定何时跟缓存暧昧往来。其中部分规则设定在协议中(HTTP 1.0 以及 1.1),部分由缓存管理员⑤设置。 ⑤缓存管理员:如果指的是浏览器缓存,则有可能就是我们服务器专家同事,在服务器上配置一些缓存规则;如果是代理缓存,则指的就是处理代理服务器这块的管理人员。 一般而言有如下常用规则N: 响应头明确说明,偶不想被缓存,则不会被缓存; 如果请求信息是需要认证或者安全加密的(如, HTTPS),相应内容也不会被缓存; 缓存如果有以下表现,则认为是fresh新鲜的(无需检查源服务器,直接发送给客户端): 含有完整的过期时间和寿命控制头信息,并且内容仍在保鲜期内,或者 缓存最近已展现,并且在不久前修改。 则内容缓存直取,绕过源服务器。 若内容陈旧,则会要求源服务器做验证 validate ,或者告诉缓存其拷贝副本是否是OK的。 特定情况下——例如,断网了,之前有过的响应缓存直取而不检查源服务器。 响应如果没有类似ETag或Last-Modified头这样的校验器,也没有明确的更新信息,通常(并不绝对)认为是不可缓存的。 总而言之,新鲜度freshness和校验validation是确定缓存内容是否可用的最重要途径。如果要展示的足够新,直接缓存取;如果检测发现展示内容并未变化,则不会再来一次完整的传输。 如何控制缓存和不缓存 有很多工具可以帮助设计师和网站管理员调整服务器缓存网站的方式,这也许需要你亲自动手对服务器的配置进行一些调整,但绝对值得。了解如何使用这些工具请参考本文后面的章节。 HTML Meta标签 vs. HTTP头信息HTML重构人员可以在文档的<head>中添加标签进行描述。这些meta标签通常用来标记不可缓存或过期时间。 Meta标签使用简单,但效果一般。因为只被少数几个浏览器宠幸,而代理缓存基本上就不访问HTML文档。尽管我们可以在页面上试图添加no-cache meta标签让页面一直是最新的,但其实没必要。 如果你的网站托管在ISP或者主机托管商那里,并且他们没有赋予您任意设置HTTP头信息的能力(比如Expires和Cache-Control),你要投诉争取,因为在你的工作中这些是必须的。 另外一方面: HTTP头信息可以让你对浏览器和代理服务器如何处理你的副本进行更多的控制。他们在HTML代码中是看不见的, 一般由Web服务器自动生成。但是,根据你使用的服务器,你可以在某种程度上进行控制。在下文中:你将看到一些有趣的HTTP头信息,以及如何在你的站点 上应用部署这些特性。 HTTP头信息发送在HTML代码之前,只能被浏览器和一些中间缓存能看到,一个典型的HTTP 1.1协议返回的头信息看上去像这样:
1 2 3 4 5 6 7 8 9 |
HTTP/1.1 200 OK Date: Fri, 30 Oct 1998 13:19:41 GMT Server: Apache/1.3.3 (Unix) Cache-Control: max-age=3600, must-revalidate Expires: Fri, 30 Oct 1998 14:19:41 GMT Last-Modified: Mon, 29 Jun 1998 02:28:12 GMT ETag: "3e86-410-3596fbbc" Content-Length: 1040 Content-Type: text/html |
[…]
View Details本文不仅适用于图片,同样实用于其它二进制文件。 需要四个类:WebRequest、WebResponse、Stream、FileStream。 WebRequest、WebResponse 的名称空间是: System.Net Stream、FileStream 的名称空间是: System.IO 核心代码 WebRequest request = WebRequest.Create("http://portrait7.sinaimg.cn/1859998982/blog/180.jpg");WebResponse response = request.GetResponse();Stream reader = response.GetResponseStream();FileStream writer = new FileStream("D:\\logo.jpg", FileMode.OpenOrCreate, FileAccess.Write);byte[] buff = new byte[512];int c = 0; //实际读取的字节数while ((c=reader.Read(buff, 0, buff.Length)) > 0){ writer.Write(buff, 0, c);}writer.Close(); 注意类 Stream,不是 StreamReader。 示例 <%@ Page Language="C#" %><%@ Import Namespace="System.Net" %><%@ Import Namespace="System.IO" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> void Page_Load(object sender, EventArgs e) { try { WebRequest request = WebRequest.Create("http://portrait7.sinaimg.cn/1859998982/blog/180.jpg"); WebResponse response = request.GetResponse(); Stream reader = response.GetResponseStream(); FileStream writer = new […]
View DetailsCardKit 是来自豆瓣的一个移动 UI 框架,使用 Card\Unit\Component 概念快速构建移动 Web 应用。应用外观跟原生应用无异。 http://ozjs.org/CardKit 转自:http://www.oschina.net/p/cardkit
View Details远程调试应用场景 部署环境:ASP.NET(C#)+IIS+Win7 64 bit 很多公司的开发模式都是将开发机器和服务器分开,也就是开发一台机,服务器一台机。而测试人员会在服务器上录入测试数据,此时报错了【由于开发程序时忽略了数据类型或者数据是否合法导致的】,如果是简单的错误那还好办,看下代码直接消灭。要是生命力比较顽强的bug,那么就需要调试了。 此时开发人员会产生几种设想: 1、赶紧把服务器的环境部署到本地,然后把生成的dll扔进去进行调试。这时会出现几种结果,如果顺利的话,通过了调试解决了bug,如果不顺利的话,就会延长bug的解决时间。不顺利的情况可能会有:对程序的配置不熟悉,本地可能在注册表缺少了对那个插件的注册,目录可能存在中文……种种的,种种的问题。 2、在服务器上装上一个Visual Studio 2008/2010/2012[后面简称vs工具],然后把程序文件拷过去,然后将生成的文件dll附加到iis进程而进行调试,哈哈,顺利解决了bug,但是一看钟表半天过去了。而且服务器多了很多文件,仅仅是为了你调试这个程序的文件。如果是管理不是很严谨的公司那还说的过去,要不然少不了要被喷一顿。 好吧,不说口水话了,进入正题。 远程调试方法 第一步:将vs工具里的Remote Debugger文件夹拷贝到目标机器。大致的目录应该是:D:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\Remote Debugger,或者从开始菜单那里可以找到它的快捷方式,如下图: 第二步:在服务器上打开Remote Debugger文件夹,如果是32位的就运行X86里面的msvsmon.exe,如果是64位的就运行X64里面的msvsmon.exe。关于32位和64位这里要注意一下,以你的IIS应用程序池为主,在应用程序池那里右键,点击高级设置,可出现以下窗体。如果启用32位应用程序设置为true的话,那么就需要运行X86里面的msvsmon.exe。 运行后会出现以下界面 第三步【最关键一步】:将你本地的账号密码设置成跟服务器一样,因为远程调试也是需要用户凭证的。账号和密码都要一致哦!!! 第四步:用vs工具打开你的程序源码,用快捷键ctrl + alt + p 打开附加进程窗体,如下图 传输:默认 限定符:默认是本机的机器名称,设置为你的服务器IP(如:192.168.1.250) 设置好按回车就可以看到250这台机子的进程,然后找到w3wp.exe这个进程,点击附加。【如果没有看到w3wp.exe,可以把下面显示所有用户的进程勾上】 接下来就尽情享受代码的调试把。 关于调试那点技术 比较一下下面两种调试的方法,看谁犯过第一种,反正我犯过。^_^ 1、为了调试某个dll而直接在Web程序里直接按F5进行调试,如果是小项目小网站的话,那没问题。如果是一个几十M甚至几百M的网站那么问题就来了。这样子的调试非常的慢,而且每次都需要重新生成整个网站的dll,那速度,是可忍孰不可忍。 2、将你需要调试的dll重新生成一下,把dll和pdb文件拷到已发布好的网站bin目录底下,然后ctrl + alt + p附加到IIS进程w3wp.exe,然后就可以调试你的dll了。这样即快又方便,做个开心的程序员吧。 结束语 好久没写过东西了,距离上一篇Installshield有1年多了,哎。以后坚持有空就写点文章,多总结自己的经验。 转自:http://www.cnblogs.com/magicchaiy/archive/2013/05/28/VS%E8%BF%9C%E7%A8%8B%E8%B0%83%E8%AF%95%E6%8A%80%E5%B7%A7.html
View Details在Asp.net MVC中,我们能非常方便的使用Ajax。这篇文章将介绍三种Ajax使用的方式,分别为原始的Ajax调用、Jquery、Ajax Helper。分别采用这三种方式结合asp.net mvc去实现一个史上最简单的留言板。 首先看一下原始的Ajax的调用的 定义CommentController,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<span style="color:blue;">public class </span><span style="color:#2B91AF;">CommentController </span>: <span style="color:#2B91AF;">Controller</span>{ <span style="color:blue;">private </span><span style="color:#2B91AF;">IList</span><<span style="color:blue;">string</span>> _comments = <span style="color:blue;">new </span><span style="color:#2B91AF;">List</span><<span style="color:blue;">string</span>>(); <span style="color:blue;">public </span><span style="color:#2B91AF;">ActionResult </span>Index() { <span style="color:blue;">return </span>View(); } <span style="color:blue;">public void </span>AddCommentServer() { <span style="color:green;"></span><span style="color:blue;">string </span>comment = Request[<span style="color:#A31515;">"comment"</span>].ToUpper(); _comments.Add(<span style="color:#A31515;">"<li>" </span>+ comment + <span style="color:#A31515;">"</li>"</span>); Response.ContentType = <span style="color:#A31515;">"text/html"</span>; Response.Write(<span style="color:blue;">string</span>.Join(<span style="color:#A31515;">"\n"</span>, _comments.ToArray())); } } |
在Asp.net MVC中添加一个custom_ajax.js,加入下面使用ajax的脚本代码,调用AddCommentServer方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<span style="color:blue;">function </span>getXmlHttpRequest() { <span style="color:blue;">var </span>xhr; <span style="color:#006400;">//check for IE implementation(s) </span><span style="color:blue;">if </span>(<span style="color:blue;">typeof </span>ActiveXObject != <span style="color:maroon;">'undefined'</span>) { <span style="color:blue;">try </span>{ xhr = <span style="color:blue;">new </span>ActiveXObject(<span style="color:maroon;">"Msxml2.XMLHTTP"</span>); } <span style="color:blue;">catch </span>(e) { xhr = <span style="color:blue;">new </span>ActiveXObject(<span style="color:maroon;">"Microsoft.XMLHTTP"</span>); } } <span style="color:blue;">else if </span>(XMLHttpRequest) { <span style="color:#006400;">//this works for Firefox, Safari, Opera </span>xhr = <span style="color:blue;">new </span>XMLHttpRequest(); } <span style="color:blue;">else </span>{ alert(<span style="color:maroon;">"对不起,你的浏览器不支持ajax"</span>); } <span style="color:blue;">return </span>xhr; } <span style="color:blue;">function </span>getMessage() { <span style="color:#006400;">//get our xml http request object </span><span style="color:blue;">var </span>xhr = getXmlHttpRequest(); <span style="color:#006400;">//prepare the request </span>xhr.open(<span style="color:maroon;">"GET"</span>, <span style="color:maroon;">"Comment/AddCommentServer?comment=" </span>+ document.getElementById(<span style="color:maroon;">"Comment"</span>).value, <span style="color:blue;">true</span>) <span style="color:#006400;">//setup the callback function </span>xhr.onreadystatechange = <span style="color:blue;">function</span>() { <span style="color:#006400;">//readyState 4 means we're done </span><span style="color:blue;">if</span>(xhr.readyState != 4) <span style="color:blue;">return</span>; <span style="color:#006400;">//populate the page with the result </span>document.getElementById(<span style="color:maroon;">'comments'</span>).innerHTML = document.getElementById(<span style="color:maroon;">'comments'</span>).innerHTML + xhr.responseText; }; <span style="color:#006400;">//fire our request </span>xhr.send(<span style="color:blue;">null</span>); } |
在View中引入此脚本,创建一个简单的表单,并添加触发的代码:
1 |
<span style="color:blue;"><</span><span style="color:maroon;">asp</span><span style="color:blue;">:</span><span style="color:maroon;">Content </span><span style="color:red;">ID</span><span style="color:blue;">="Content2" </span><span style="color:red;">ContentPlaceHolderID</span><span style="color:blue;">="MainContent" </span><span style="color:red;">runat</span><span style="color:blue;">="server"> <</span><span style="color:maroon;">h4</span><span style="color:blue;">></span>Comments<span style="color:blue;"></</span><span style="color:maroon;">h4</span><span style="color:blue;">> <</span><span style="color:maroon;">ul </span><span style="color:red;">id</span><span style="color:blue;">="comments"> </</span><span style="color:maroon;">ul</span><span style="color:blue;">> </span><span style="background:yellow;"><%</span><span style="color:blue;">= </span>Html.TextArea(<span style="color:#A31515;">"Comment"</span>, <span style="color:blue;">new</span>{rows=5, cols=50}) <span style="background:yellow;">%></span><span style="color:blue;"><</span><span style="color:maroon;">button </span><span style="color:red;">type</span><span style="color:blue;">="submit" </span><span style="color:red;">onclick</span><span style="color:blue;">="getMessage()"></span>Add Comment<span style="color:blue;"></</span><span style="color:maroon;">button</span><span style="color:blue;">> <</span><span style="color:maroon;">span </span><span style="color:red;">id</span><span style="color:blue;">="indicator" </span><span style="color:red;">style</span><span style="color:blue;">="</span><span style="color:red;">display</span><span style="color:blue;">:none"><</span><span style="color:maroon;">img </span><span style="color:red;">src</span><span style="color:blue;">="http://www.cnblogs.com/content/load.gif" </span><span style="color:red;">alt</span><span style="color:blue;">="loading..." /></</span><span style="color:maroon;">span</span><span style="color:blue;">> </</span><span style="color:maroon;">asp</span><span style="color:blue;">:</span><span style="color:maroon;">Content</span><span style="color:blue;">><</span><span style="color:maroon;">asp</span><span style="color:blue;">:</span><span style="color:maroon;">Content </span><span style="color:red;">ID</span><span style="color:blue;">="Content3" </span><span style="color:red;">ContentPlaceHolderID</span><span style="color:blue;">="headContent" </span><span style="color:red;">runat</span><span style="color:blue;">="server"> <</span><span style="color:maroon;">script </span><span style="color:red;">src</span><span style="color:blue;">="http://www.cnblogs.com/Scripts/custom_ajax.js" </span><span style="color:red;">type</span><span style="color:blue;">="text/javascript"></</span><span style="color:maroon;">script</span><span style="color:blue;">></</span><span style="color:maroon;">asp</span><span style="color:blue;">:</span><span style="color:maroon;">Content</span><span style="color:blue;">></span> |
1 |
<span style="color:blue;"><span style="color:#000000;"> 效果如下:</span></span> |
1 |
<pre class="code"><span style="color:blue;"><a href="http://images.cnblogs.com/cnblogs_com/zhuqil/WindowsLiveWriter/Asp.netmvc2Ajax_EBA5/3_2.png"><img width="900" height="321" title="3" style="border-width:0px;display:inline;" alt="3" src="//images.cnblogs.com/cnblogs_com/zhuqil/WindowsLiveWriter/Asp.netmvc2Ajax_EBA5/3_thumb.png" border="0" /></a></span> |
1 |
<span style="color:#000000;"><span style="font-size:24px;"><strong> </strong></span></span> |
1 |
<span style="color:#000000;"><span style="font-size:24px;"><strong> </strong></span></span> |
1 |
<span style="color:#000000;"><span style="font-size:24px;"><strong>第二种方式:利用Jquery:</strong></span></span> |
1 |
<span style="color:#000000;"> 在控制器中添加代码IndexJquery方法和AddComment方法的代码,<span style="color:#2B91AF;">CommentController代码</span>如下所示</span> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<span style="color:blue;">public class </span><span style="color:#2B91AF;">CommentController </span>: <span style="color:#2B91AF;">Controller</span>{ <span style="color:blue;">private </span><span style="color:#2B91AF;">IList</span><<span style="color:blue;">string</span>> _comments = <span style="color:blue;">new </span><span style="color:#2B91AF;">List</span><<span style="color:blue;">string</span>>(); <span style="color:blue;">public </span><span style="color:#2B91AF;">ActionResult </span>Index() { <span style="color:blue;">return </span>View(); } <span style="color:blue;">public </span><span style="color:#2B91AF;">ActionResult </span>IndexJquery() { <span style="color:blue;">return </span>View(); } <span style="color:blue;">public </span><span style="color:#2B91AF;">ActionResult </span>AddComment(<span style="color:blue;">string </span>comment) { _comments.Add(<span style="color:#A31515;">"<li>" </span>+ comment + <span style="color:#A31515;">"</li>"</span>); <span style="color:blue;">return </span>Content(<span style="color:blue;">string</span>.Join(<span style="color:#A31515;">"\n"</span>, _comments.ToArray())); } <span style="color:blue;">public void </span>AddCommentServer() { |
1 2 3 4 5 6 7 8 9 |
<span style="color:green;"></span><span style="color:blue;">string </span>comment = Request[<span style="color:#A31515;">"comment"</span>].ToUpper(); _comments.Add(<span style="color:#A31515;">"<li>" </span>+ comment + <span style="color:#A31515;">"</li>"</span>); Response.ContentType = <span style="color:#A31515;">"text/html"</span>; Response.Write(<span style="color:blue;">string</span>.Join(<span style="color:#A31515;">"\n"</span>, _comments.ToArray())); } } |
1 |
根据IndexJquery,<span style="color:blue;"><span style="color:#000000;">创建View表单IndexJquery.aspx:</span></span> |
1 |
<span style="color:blue;"><</span><span style="color:maroon;">h4</span><span style="color:blue;">></span>Comments<span style="color:blue;"></</span><span style="color:maroon;">h4</span><span style="color:blue;">> <</span><span style="color:maroon;">ul </span><span style="color:red;">id</span><span style="color:blue;">="comments"> </</span><span style="color:maroon;">ul</span><span style="color:blue;">> </span><span style="background:yellow;"><%</span><span style="color:blue;">using </span>(Html.BeginForm(<span style="color:#A31515;">"AddComment"</span>,<span style="color:#A31515;">"Comment"</span>,<span style="color:#2B91AF;">FormMethod</span>.Post,<span style="color:blue;">new </span>{@class=<span style="color:#A31515;">"hijax"</span>})) { <span style="background:yellow;">%></span><span style="background:yellow;"><%</span><span style="color:blue;">= </span>Html.TextArea(<span style="color:#A31515;">"Comment"</span>, <span style="color:blue;">new</span>{rows=5, cols=50}) <span style="background:yellow;">%></span><span style="color:blue;"><</span><span style="color:maroon;">button </span><span style="color:red;">type</span><span style="color:blue;">="submit"></span>Add Comment<span style="color:blue;"></</span><span style="color:maroon;">button</span><span style="color:blue;">> <</span><span style="color:maroon;">span </span><span style="color:red;">id</span><span style="color:blue;">="indicator" </span><span style="color:red;">style</span><span style="color:blue;">="</span><span style="color:red;">display</span><span style="color:blue;">:none"><</span><span style="color:maroon;">img </span><span style="color:red;">src</span><span style="color:blue;">="http://www.cnblogs.com/content/load.gif" </span><span style="color:red;">alt</span><span style="color:blue;">="loading..." /></</span><span style="color:maroon;">span</span><span style="color:blue;">> </span><span style="background:yellow;"><%</span> } <span style="background:yellow;">%></span> |
1 |
<span style="color:#000000;"> 在View中引用Jquery:</span> |
1 |
<span style="color:blue;"><</span><span style="color:maroon;">script </span><span style="color:red;">src</span><span style="color:blue;">="http://www.cnblogs.com/Scripts/jquery-1.4.1.min.js" </span><span style="color:red;">type</span><span style="color:blue;">="text/javascript"></</span><span style="color:maroon;">script</span><span style="color:blue;">></span> |
添加下面脚本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<span style="color:blue;"><</span><span style="color:maroon;">script </span><span style="color:red;">type</span><span style="color:blue;">="text/javascript"> </span><span style="color:#006400;">//execute when the DOM has been loaded </span>$(document).ready(<span style="color:blue;">function </span>() { <span style="color:#006400;">//wire up to the form submit event </span>$(<span style="color:maroon;">"form.hijax"</span>).submit(<span style="color:blue;">function </span>(event) { event.preventDefault(); <span style="color:#006400;">//prevent the actual form post </span>hijack(<span style="color:blue;">this</span>, update_sessions, <span style="color:maroon;">"html"</span>); }); }); <span style="color:blue;">function </span>hijack(form, callback, format) { $(<span style="color:maroon;">"#indicator"</span>).show(); $.ajax({ url: form.action, type: form.method, dataType: format, data: $(form).serialize(), completed: $(<span style="color:maroon;">"#indicator"</span>).hide(), success: callback }); } <span style="color:blue;">function </span>update_sessions(result) { <span style="color:#006400;">//clear the form </span>$(<span style="color:maroon;">"form.hijax"</span>)[0].reset(); $(<span style="color:maroon;">"#comments"</span>).append(result); } <span style="color:blue;"></</span><span style="color:maroon;">script</span><span style="color:blue;">></span> |
1 |
<span style="color:blue;"><span style="color:#000000;"> </span></span> |
1 |
1 |
<span style="color:blue;"><span style="color:#000000;"> </span></span> |
1 |
<pre class="code"><span style="background:yellow;"> </span> |
1 |
<span style="color:blue;"><span style="color:#000000;"> </span></span> |
1 |
<span style="color:blue;"><span style="color:#000000;"><span style="font-size:24px;"><strong> </strong></span></span></span> |
1 |
<span style="color:blue;"><span style="color:#000000;"><span style="font-size:24px;"><strong> </strong></span></span></span> |
效果:与方式一效果一样
1 |
1 |
<span style="color:blue;"><span style="color:#000000;"><span style="font-size:24px;"><strong>第三种方式:Ajax Helper。</strong></span></span></span> |
1 |
<span style="color:blue;"></span> |
1 |
<span style="color:blue;"><span style="color:#000000;"> 将最简单的留言板修改成Ajax Helper的方式。</span></span> |
1、首先了解一下Ajax Helper下面四种方法。 a、Ajax.ActionLink():它将渲染成一个超链接的标签,类似于Html.ActionLink()。当它被点击之后,将获取新的内容并将它插入到HTML页面中。 b、Ajax.BeginForm():它将渲染成一个HTML的Form表单,类似于Html.BeginForm()。当它提交之后,将获取新的内容并将它插入到HTML页面中。 c、Ajax.RouteLink():Ajax.RouteLink()类似于Ajax.ActionLink()。不过它可以根据任意的routing参数生成URL,不必包含调用的action。使用最多的场景是自定义的IController,里面没有action。 d、Ajax.BeginRouteForm():同样Ajax.BeginRouteForm()类似于Ajax.BeginForm()。这个Ajax等同于Html.RouteLink()。 这个例子中使用Ajax.BeginForm(),下面具体了解Ajax.BeginForm()的参数。看下面代码
1 2 3 4 5 |
<span style="background:yellow;"><%</span><span style="color:blue;">using </span>(Ajax.BeginForm(<span style="color:#A31515;">"AddComment"</span>, <span style="color:blue;">new </span><span style="color:#2B91AF;">AjaxOptions </span>{ HttpMethod = <span style="color:#A31515;">"POST"</span>, UpdateTargetId = <span style="color:#A31515;">"comments"</span>, InsertionMode = <span style="color:#2B91AF;">InsertionMode</span>.InsertAfter })) { <span style="background:yellow;">%></span> |
actionName:AddComment(action的名字) controllerName:CommentController(Controller的名字) ajaxOptions: HttpMethod:Ajax的请求方式,这里为POST UpdateTargetId :Ajax请求的结果显示的标签的ID,这里为comments InsertionMode:将Ajax结果插入页面的方式,这里将ajax的结果放置到comments的后面 2、实现: 在CommentController中添加IndexAjaxHelp方法。
1 2 3 4 |
<span style="color:blue;">public </span><span style="color:#2B91AF;">ActionResult </span>IndexAjaxHelp() { <span style="color:blue;">return </span>View(); } |
根据IndexAjaxHelp生成View表单IndexAjaxHelp.aspx,定义表单:
1 2 3 4 5 |
<span style="color:blue;"><</span><span style="color:maroon;">h4</span><span style="color:blue;">></span>Comments<span style="color:blue;"></</span><span style="color:maroon;">h4</span><span style="color:blue;">> <</span><span style="color:maroon;">ul </span><span style="color:red;">id</span><span style="color:blue;">="comments"> </</span><span style="color:maroon;">ul</span><span style="color:blue;">> </span><span style="background:yellow;"><%</span><span style="color:blue;">using </span>(Ajax.BeginForm(<span style="color:#A31515;">"AddComment"</span>, <span style="color:blue;">new </span><span style="color:#2B91AF;">AjaxOptions </span>{ HttpMethod = <span style="color:#A31515;">"POST"</span>, UpdateTargetId = <span style="color:#A31515;">"comments"</span>, InsertionMode = <span style="color:#2B91AF;">InsertionMode</span>.InsertAfter })) { <span style="background:yellow;">%></span><span style="background:yellow;"><%</span><span style="color:blue;">= </span>Html.TextArea(<span style="color:#A31515;">"Comment"</span>, <span style="color:blue;">new</span>{rows=5, cols=50}) <span style="background:yellow;">%></span><span style="color:blue;"><</span><span style="color:maroon;">button </span><span style="color:red;">type</span><span style="color:blue;">="submit"></span>Add Comment<span style="color:blue;"></</span><span style="color:maroon;">button</span><span style="color:blue;">> </span><span style="background:yellow;"><%</span> } <span style="background:yellow;">%></span> |
要在此View中添加下面两个脚本文件:
1 |
<span style="color:blue;"><</span><span style="color:maroon;">script </span><span style="color:red;">src</span><span style="color:blue;">="http://www.cnblogs.com/Scripts/MicrosoftAjax.js" </span><span style="color:red;">type</span><span style="color:blue;">="text/javascript"></</span><span style="color:maroon;">script</span><span style="color:blue;">> <</span><span style="color:maroon;">script </span><span style="color:red;">src</span><span style="color:blue;">="http://www.cnblogs.com/Scripts/MicrosoftMvcAjax.js" </span><span style="color:red;">type</span><span style="color:blue;">="text/javascript"></</span><span style="color:maroon;">script</span><span style="color:blue;">></span> |
1 |
这样就行了,我们发现比用Jquery方便很多,但是使用Jquery将灵活很多。 3、效果:和方式一样。 总结:本文非常的简单,在asp.net mvc中实现了3中ajax的调用方式,实现了一个最简单的留言板程序。推荐使用Jquery和Ajax Helper这两种。Ajax Helper使用非常简单,Jquery比较灵活。 更新:三种方式都实现了一个最简单的留言板程序 参考: ASP.NET MVC 2 In Action Pro ASP.NET MVC 2 Framework, Second Edition 代码:http://files.cnblogs.com/zhuqil/AjaxDemo.rar 作者:朱祁林出处:http://zhuqil.cnblogs.com本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
View Details
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
/// <summary> /// 生成缩略图 /// </summary> /// <param name="imgPath">源图片路径</param> /// <param name="thumbnailPath">缩略图保存路径</param> /// <param name="newWidth">新宽度</param> /// <param name="newHeight">新高度</param> /// <param name="addSpace">是否添加空白</param> /// <returns></returns> public static void Thumbnail(string imgPath, string thumbnailPath, int newWidth, int newHeight, bool addSpace) { int sW, sH; // 按比例缩放 var imgSource = Image.FromFile(imgPath); var sWidth = imgSource.Width; var sHeight = imgSource.Height; if (sHeight > newHeight || sWidth > newWidth) { if ((sWidth * newHeight) > (sHeight * newWidth)) { sW = newWidth; sH = (newWidth * sHeight) / sWidth; } else { sH = newHeight; sW = (sWidth * newHeight) / sHeight; } } else { sW = sWidth; sH = sHeight; } var outBmp = addSpace ? new Bitmap(newWidth, newHeight) : new Bitmap(sW, sH); var x = 0; var y = 0; if (addSpace) { var whRate = newWidth > newHeight ? true : false; //宽是否大于高(新尺寸) x = whRate ? (newWidth - sW) / 2 : x; y = whRate ? (newHeight - sH) / 2 : y; } var g = Graphics.FromImage(outBmp); // 设置画布的描绘质量 g.CompositingQuality = CompositingQuality.HighQuality; g.SmoothingMode = SmoothingMode.HighQuality; g.InterpolationMode = InterpolationMode.HighQualityBicubic; g.DrawImage(imgSource, new Rectangle(x, y, sW, sH), new Rectangle(0, 0, imgSource.Width, imgSource.Height), GraphicsUnit.Pixel); g.Dispose(); try { //保存图片 outBmp.Save(thumbnailPath, ImageFormat.Jpeg); } finally { imgSource.Dispose(); g.Dispose(); outBmp.Dispose(); } } |
我们使用的是哪个 PHP 版本? 带有 Suhosin-补丁的PHP 5.3.10-1ubuntu3.6, 安装于 Ubuntu 12.04 LTS. PHP如同是网络世界的百年老龟。它的外壳上刻有一个丰富的,令人费解的,粗糙的历史。在一个共享主机的环境下,它的配置可能会限制你能做什么事情。 为了保留一丝明智,我们需要只专注于一个版本的PHP。截至2013年4月30,该版本是 带有Suhosin补丁的PHP5.3.10-1ubuntu3.6 。如果你使用apt-get从一个Ubuntu12.04 LTS服务器来安装PHP的话,你所得到的版本就是这个。换句话说,许多人在默认情况下已经很明智地使用了它。 您可能会发现本文这些解决方案能工作于不同或更旧版本的PHP。如果是这样的话,就要由你来研究在这些旧版本中的细微错误或安全问题的影响了。 保存密码 使用 phpass 库计算密码的哈希值进行比较。 用 phpass 0.3 进行的测试。 散列化是在把用户密码保存进数据库之前对其进行保护的标准方法。许多常见的散列算法,如MD5,乃至SHA1,用于存储密码都是不安全的,因为黑客可以使用这些散列算法轻松破解密码。 要散列化密码最安全的方法是使用bcrypt算法。开源的phpass 库用一个易于使用的类来提供这个功能。 例子: view source print? 01 <?php 02 // 包含phpass库 03 require_once('phpass-0.3/PasswordHash.php'); 04 05 // 初始化散列器为不可移植(这样更安全) 06 $hasher= newPasswordHash(8, false); 07 08 // 计算密码哈希值。$hashedPassword 将会是一长为60个字符的字符串. 09 $hashedPassword= $hasher->HashPassword('my super cool password'); 10 11 // 你现在可以安全地保存$hashedPassword到数据库中! 12 13 // 通过比较用户输入内容(产生的哈希值)和我们之前计算出的哈希值,来判断用户是否输入了正确的密码 14 $hasher->CheckPassword('the wrong password', $hashedPassword); // 返回假 15 16 $hasher->CheckPassword('my super cool password', $hashedPassword); // 返回真 17 ?> 陷阱 很多来源会建议你在计算密码的哈希值之前先给密码加点“作料”。这是个好主意,phpass已经利用HashPassword() 函数中的一部分代码来为你给密码加了作料。 这就意味着你并不需要自己再亲自做这个了。 进一步阅读 […]
View Detailsasp已经诞生18年了,是我工作用的第一门语言。 ASP是Active Server Page的缩写,意为“动态服务器页面”。ASP是微软公司开发的代替CGI脚本程序的一种应用,它可以与数据库和其它程序进行交互,是一种简单、方便的编程工具。ASP的网页文件的格式是 .asp。现在常用于各种动态网站中。 发展史 从1996年ASP诞生到2012年已经过去了17年。在这短短的17年中,ASP发生了重大的变化,直到现在的ASP。 asp的第一版是0.9测试版,自从1996年ASP1.0诞生,它给Web开发界带来了福音。早期的Web程序开发是十分繁琐的,以至于要制作一个简单的动态页面需要编写大量的C代码才能完成,这对于普通的程序员来说有点难了。而ASP却允许使用VBScript这种的简单脚本语言,编写嵌入在HTML网页中的代码。在进行程序设计的时候可以使用它的内部组件来实现一些高级功能(例如Cookie)。它的最大的贡献在于它的ADO(ActiveX Data Object),这个组件使得程序对数据库的操作十分简单,所以进行动态网页设计也变成一件轻松的事情。因此一夜之间,Web程序设计不再是想像中的艰巨任务,仿佛很多人都可以一显身手。 到了1998年,微软发布了ASP 2.0。它是Windows NT4 Option Pack的一部分,作为IIS(Internet Information Services,互联网信息服务) 4.0的外接式附件。它与ASP 1.0的主要区别在于它的外部组件是可以初始化的,这样,在ASP程序内部的所有组件都有了独立的内存空间,并可以进行事务处理。 到了2000年,随着Windows 2000的成功发布,这个操作系统的IIS(Internet Information Services,互联网信息服务) 5.0所附带的ASP 3.0也开始流行。与ASP 2.0相比,ASP 3.0的优势在于它使用了COM+,因而其效率会比它前面的版本要好,并且更稳定。 2001年,ASP·NET出现了。在刚开始开发的时候,它的名字是ASP+,但是,为了与微软的·NET计划相匹配,并且要表明这个ASP版本并不是对ASP 3.0的补充,微软将其命名为ASP·NET。ASP·NET在结构上与前面的版本大相径庭,它几乎完全是基于组件和模块化的,Web应用程序的开发人员使用这个开发环境可以实现更加模块化的、功能更强大的应用程序。 网页特点ASP是一种服务器端脚本编写环境,可以用来创建和运行动态网页或Web应用程序。ASP网页可以包含HTML标记、普通文本、脚本命令以及COM组件等。利用ASP可以向网页中添加交互式内容(如在线表单),也可以创建使用HTML网页作为用户界面的web应用程序。与HTML相比,ASP网页具有以下特点:⑴利用ASP可以实现突破静态网页的一些功能限制,实现动态网页技术;⑵ASP文件是包含在HTML代码所组成的文件中的,易于修改和测试;⑶服务器上的ASP解释程序会在服务器端执行ASP程序,并将结果以HTML格式传送到客户端浏览器上,因此使用各种浏览器都可以正常浏览ASP所产生的网页;⑷ASP提供了一些内置对象,使用这些对象可以使服务器端脚本功能更强。例如可以从web浏览器中获取用户通过HTML表单提交的信息,并在脚本中对这些信息进行处理,然后向web浏览器发送信息;⑸ASP可以使用服务器端ActiveX组件来执行各种各样的任务,例如存取数据库、发送Email或访问文件系统等;⑹由于服务器是将ASP程序执行的结果以HTML格式传回客户端浏览器,因此使用者不会看到ASP所编写的原始程序代码,可防止ASP程序代码被窃取;⑺ 方便连接ACCESS与SQL数据库;⑻开发需要有丰富的经验,否则会留出漏洞,让骇客(cracker)利用进行注入攻击。ASP也不仅仅局限于与HTML结合制作WEB网站,而且还可以与XHTML和WML语言结合制作WAP手机网站。但是其原理也是一样的。 工作原理当在Web站点中融入ASP功能后,将发生以下事情:1、用户向浏览器地址栏输入网址,默认页面的扩展名是.asp。2、浏览器向服务器发出请求。3、服务器引擎开始运行ASP程序。4、ASP文件按照从上到下的顺序开始处理,执行脚本命令,执行HTML页面内容。5、页面信息发送到浏览器。 生成txtFileName = "idcpcw.txt" '要保存的文本文件名Set fso = CreateObject("Scripting.FileSystemObject") '建立fso对象Set MyFile = fso.CreateTextFile(Server.mapPath(TxtFileName), True) '建立对象MyFile.WriteLine "文本的内容" & uuu '将name的值写入文本文件,uuu为数据库的数据MyFile.WriteLine "文本的内容" & uuu '同上[1]
View Details今天编译spacebuilder程序,发现编译可以通过,但是在发布时,却出现了如下的错误信息: 错误 110 该项目中不存在目标“PipelinePreDeployCopyAllFilesToOneFolder”。 E:\工作项目\开发程序\aspcool\Spacebuilder_V3.2.0.1_SDK\Spacebuilder\Web\Web.csproj 0 0 Web 经过在网上搜索,发现下面的解决方法: 用记事本打开出错的项目文件(A.csproj). 末尾 <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="'$(Solutions.VSVersion)' == '10.0'" /> <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="'$(Solutions.VSVersion)' == '9.0'" /> <!--<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />--> 修改为 <!--<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="'$(Solutions.VSVersion)' == '10.0'" /> <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="'$(Solutions.VSVersion)' == '9.0'" />--> <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" /> 经过测试,发布成功,谢谢smodi的方法。 转自:http://club.aspcool.com/News.aspx/T-3
View Details