原文:http://hi.baidu.com/dream621/blog/item/7f60de82781b37b96d81196d.html
PHP代码
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- function pdf2png($PDF,$Path){
- if(!extension_loaded('imagick')){
- return false;
- }
- if(!file_exists($PDF)){
- return false;
- }
- $IM = new imagick();
- $IM->setResolution(120,120);
- $IM->setCompressionQuality(100);
- $IM->readImage($PDF);
- foreach ($IM as $Key => $Var){
- $Var->setImageFormat('png');
- $Filename = $Path.'/'.md5($Key.time()).'.png';
- if($Var->writeImage($Filename) == true){
- $Return[] = $Filename;
- }
- }
- return $Return;
- }
主要是思路不错就转发了
本文很长,来自于博客园,并不是说文章内容很有深意,但是因为作者在介绍的时候的step by step,也能让人体会到了代码复用并非全部是用在服务端的OO,对于客户端其实也能够做到OO。
原文网址:http://www.cnblogs.com/KenBlove/archive/2009/03/16/1413746.html
内容摘抄:(太多了,仅摘抄部份原话)
大家都知道,客户端检测不单可以让用户获得更好的体验,而且可以通过校验数据大大减少客户端和服务器端的往返次数,减少服务器负担。在这里,小弟打算回顾一下自己在客户端检测方面的学习历程和采用方法,如果大家有什么更好的方法或者建议,欢迎提出来共享!共同进步!
第一阶段是:续项强写
每个人都基本会经过这个阶段,就是对检测内容每个都手工校验。
第二阶段:集中消灭
相信不少初学者现在还是处于这个阶段,这阶段的同学们已经被第一阶段折磨怕了。很快就想出了集中消灭相同类型检测的方法。就是写检测函数
第三阶段:链式的威力
看着一大堆if else总是心里觉得不舒服,对吧?一串串的又不是羊肉串,虽然不能吃,也要消灭它们!这时候,是Javascript的prototype出场的时候了。通过扩展prototype,可以获得简洁优雅的代码
第四阶段:自定义属性
第五阶段:可配置
作者最后还附上了源码,建议全文查看
作者: Fenng | 可以转载, 转载时务必以超链接形式标明文章原始出处和作者信息及版权声明
网址: http://www.dbanotes.net/arch/heroku_architecture.html
以上是作者和原文的信息。因为可能会布置一台服务器,所以对这方面就有点想法,作者是在对RUBY方面的架构进行学习和分析,但我想,对于PHP方面,应该也会有参考价值。已经开始有想法转硬件了,哈哈。说说而己……
原文如下:
这几天给我印象比较深的是 HeroKu ,提供 Ruby 快速部署环境并提供托管能力,他们的架构图做得十分漂亮,一幅图胜过千言万语,要是对 Web 架构感兴趣,都别问架构师了,看看 HeroKu 的架构估计就明白个差不多了 :)
概览图
好的架构图是画出来的,好的架构未必是设计出来的,最后架构好不好,还要看持续的改进能力。
HTTP 反向代理
使用 Nginx , 这一层只进行 HTTP-level 的处理。Nginx 现在是不二选择。
HTTP Cache
对于静态内容,使用 Varnish 进行缓存。如果你在 Squid 和 Varnish 之间作选择,这里已经投了一票。
路由网(Routing Mesh)
用 Erlang 实现的架构组件,路由寻址,用以提升可用性和扩展性。
动态网格(Dyno Grid)
用户部署的代码运行在这里,可以简单看成是应用服务器集群环境,只是粒度更小一点而已。
对于 Dyno Grid 的进一步信息:
服务器操作系统是 Debian ;Ruby VM 是 MRI ,开源,C 写的;App Server 用的 Thin,他们说 Thin 比 Mongrel 更精炼;Rack,应用服务器接口;Rack 中间件,可选组件;框架,任何 Rack 兼容的都成;最后是客户托管的代码。
数据库
PostgreSQL,也可以采用远程数据库。
Memory Cache
Memcached ,居家旅行架构必备。
这几张图看下来,多少算是对 Ruby 环境有了一些感性认识。可以进一步查看 HeroKu 提供的文档,包含了一些代码实现上的准则。
部署是基于 Git 的。不知道大家有没有注意到 Git 在最近一年来的爆发? 超过 SVN 或许不是不可能的。
国内热炒"云计算"的,跟人家学学吧,与其整天帮着客户开发定制软件,还不如给客户提供一些弹性应用托管环境,起码看起来靠谱一些。
HeroKu ,不读 Hero-Ku, 读作 Her-oh-koo, 挺有趣
--EOF--
图的来源:HeroKu Platform Architecture
本例子来自博客园,其实关于Autocompleted的例子,用jquery的话,是很多很多,但那都是国外的,难得有国内的例子,看到了就复制回来一份,呵呵
原文:http://www.cnblogs.com/cntlis/archive/2009/03/14/1412144.html
数据采用JSON,格式为{keylist:[{'keyname':关键字1,'keyextend':扩展文字(譬如说结果数目)},{'keyname':关键字2,'keyextend':扩展文字(譬如说结果数目)}]}
JS代码(当成JS代码插入的时候,高亮会超时,所以,用HTML格式了一下)
- /**//*
- * jQuery AutoComplete
- *
- * Author: cntlis
- * http://blog.csdn.net/cntlis
- *
- * Licensed like jQuery, see http://docs.jquery.com/License
- *
- * 作者:cntlis
- * QQ:8112857
- */
- $.fn.AutoComplete = function(url,option){
- var me= this;
- var strKey= $(me).val();
- var strKeyBak= "";
- var isShow = false;
- var doption={
- iwidth: '0px', //下拉框的宽度
- iLengthLower: 1, //当表单的长度大于iLengthLower小于iLengthUpper时才开始执行搜索
- iLengthUpper: 50,
- strPara: "Keyword", //变量名称
- zIndex: 1, //提示框的Z-INDEX值
- hasscroll: 0, //是否出现滚动条0无1有
- hasclose: 1, //是否拥有关闭窗口
- desfun:function(){}
- };
-
- $.extend(doption,option);
- var iLengthLower= doption.iLengthLower;
- var iLengthUpper= doption.iLengthUpper;
- var strPara= doption.strPara;
- if ($("#autocomplete").length<1){$("body").append("<div id='autocomplete' class='autocompletefloor'></div>");}
- $("#autocomplete").hide();
-
- $(me).keyup(function(e){keysearch(e.keyCode);});
- $(me).keydown(function(e){LineSelect(e.keyCode);});
- $(me).bind("blur",function(){
- strKeyBak= $("#autocomplete ul .selected .keyname").text(); //为click事件增加处理
- if (strKeyBak.length>0 && strKeyBak!=$(me).val()){
- $(me).val(strKeyBak);
- doption.desfun();
- };
- floorHide();
- });
-
- var encode=function(v){//如果包含中文就escape,避免重复escape)
- return escape(v).replace(/\+/g, '%2B').replace(/\"/g,'%22').replace(/\'/g, '%27').replace(/\//g,'%2F');
- }
-
- function floorHide(){
- $("#autocomplete").hide().html("");
- strKey= "";
- isShow = false;
- }
-
- function floorShow(){
- var p= $(me).offset();
- var w= (doption.iwidth == "0px") ? $(me).width()+2 : doption.iwidth;
- $("#autocomplete").css({
- 'z-index:':doption.zIndex,
- width:w,
- top:parseInt(p.top+$(me).outerHeight())+"px",
- left:parseInt(p.left)+"px"
- }).show();
- strKey= "";
- isShow = true;
- }
-
- function keysearch(code){
- var strKeyNow=$(me).val();
- if(code == 38 || code == 40 || code == 13 || code == 27 || code == 9) return; //TAB/回车、ESC、向上、向下
- if((strKey == "" || strKeyNow != strKey) && strKeyNow.length >= iLengthLower && strKeyNow.length <= iLengthUpper){
- $.ajax({
- type: "Get",
- dataType: "json",
- url: url,
- data: strPara != "" ? strPara + "=" + encode(strKeyNow) : "",
- success: function(json){
- jsonjson=json.keylist;
- if (json.length>0){
- //获取搜索数据
- var strContent= "<ul>";
- $.each(json, function(i, n){
- if(n.keyname.length>0){ //如果
- //alert(n.keyname);
- strContent+= '<li class="keyinfo"><span class="keyname">'+n.keyname+'</span>';
- try{
- if (n.keyextend.length>0){strContent+='<span class="keyextend">'+n.keyextend+'</span>';}
- }catch(E){};
- strContent+= '</li>';
- };
- });
- if (doption.hasclose==1){
- strContent+= '<li class="close"><span>关闭</span></li>';
- }
- strContent+='</ul>';
- $("#autocomplete").html(strContent);
- $("#autocomplete .keyinfo").mouseover(function(){$("#autocomplete .selected").removeClass("selected");$(this).removeClass("unselected").addClass("selected");}).mouseout(function(){$(this).removeClass("selected").addClass("unselected");}).click(function(){if(strKeyBak.length()>0){$(me).val(strKeyBak);}});
- floorShow();
- }else{
- //没有搜索数据
- floorHide();
- return;
- }
- }
- });
- strKey=$(me).val();
- }
- if(strKey.length == 0 || strKey.length <= iLengthLower || strKey.length >= iLengthUpper) floorHide();
- }
-
- function LineSelect(code){
- if(code == 27){floorHide();};//回车键、ESC键
- if(code == 13){floorHide();doption.desfun();};
- if(!isShow) return;
- ObjSelected=$("#autocomplete ul .selected");
- if (ObjSelected.length>0){ //如果已经有选定
- //alert('dasfdas');
- if(code == 38){ //向上键
- if(ObjSelected.prev().text() != ""){ //如果不是第一个数据
- ObjSelected.removeClass("selected").addClass("unselected").prev().removeClass("unselected").addClass("selected");
- $(me).val($("#autocomplete ul .selected .keyname").text());
- }else{
- ObjSelected.removeClass("selected").addClass("unselected");
- $("#autocomplete .keyinfo:last").removeClass("unselected").addClass("selected");
- $(me).val($("#autocomplete ul .selected .keyname").text());
- }
- }else if (code == 40){ //向下键
- if(ObjSelected.next().text() != ""){ //如果不是第一个数据
- ObjSelected.removeClass("selected").addClass("unselected").next().removeClass("unselected").addClass("selected");
- $(me).val($("#autocomplete ul .selected .keyname").text());
- }else{
- ObjSelected.removeClass("selected").addClass("unselected");
- $("#autocomplete .keyinfo:first").removeClass("unselected").addClass("selected");
- $(me).val($("#autocomplete ul .selected .keyname").text());
- }
- }
- }else if(code == 38){
- $("#autocomplete .keyinfo:last").removeClass("unselected").addClass("selected");
- $(me).val($("#autocomplete .keyinfo:last .keyname").text());
- }else if(code == 40){
- $("#autocomplete .keyinfo:first").removeClass("unselected").addClass("selected");
- $(me).val($("#autocomplete .keyinfo:first .keyname").text());
- }
- }
- }
CSS代码
- #autocomplete{}{ border: 1px solid #000; position: absolute; }
- /**//*每行的格式*/
- #autocomplete li{}{ display: block; text-align: left; height: 20px; line-height: 20px; background-color: #fff; cursor: default; padding: 0 5px; clear: both; }
- /**//*鼠标选中时的格式*/
- #autocomplete .selected{}{ background-color: #565da9; color: #fff; overflow: hidden; }
- /**//*鼠标离开时代格式*/
- #autocomplete .unselected{}{ background-color: #fff; color: #666; }
- /**//*关键字信息*/
- #autocomplete .keyname{}{ display: block; float: left; }
- /**//*关键字扩展信息*/
- #autocomplete .keyextend{}{ display: block; float: right; color: green; }
- #autocomplete .unselected .keyextend{}{ color: green; }
- #autocomplete .selected .keyextend{}{ color: #fff; }
- /**//*关闭*/
- #autocomplete .close{}{ text-align: right; }
- #autocomplete .close span{}{ color: blue; cursor: pointer; text-decoration: underline; }
调用范例
$("#Keyword").AutoComplete("search.asp");
是不是很简单的?只是search.asp返回的数据要是上面所提供的格式,对于PHP来说就太方便了,只要生成相应的数组,然后json_encode一下就全出来了,呵呵
不说啥了,直接上原文:
两篇文章的地址分别为:http://rdc.taobao.com/blog/qa/?p=857
http://rdc.taobao.com/blog/qa/?p=882
什么是xss漏洞
XSS又叫CSS英文缩写为Cross Site Script
中文意思为跨站脚本攻击
具体内容指的是恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,
嵌入其中Web里面的html代码会被执行,从而达到恶意用户的特殊目的.
xss的漏洞危害
- 获取用户cookie
- 修改页面信息
- 浏览器劫持
- 与其他漏洞结合(如:csrf漏洞)
- 其他
xss漏洞实例演示
xss漏洞是如何产生的
以下Velocity模板VM中常见的代码
- <span>$!productName</span>
- <script>var from = ‘$!rundata.Parameters.getString(’from’)';</script>
对于第一种类型的代码我们可以输入变量为
<iframe src=http://hacker.com></iframe>
第一种类型的代码将变为
<span><iframe src=http://hacker.com></iframe></span>
对于第二种类型的代码我们可以输入变量为
‘;hackerFunction(document.cookie);’
第二种类型的代码将变为
<script>var from = ”;hackerFunction(document.cookie);”; </script>
以上两种类型的代码都轻易的被植入了恶意的脚本,也就是说产生了传说中的xss漏洞。
xss漏洞如何预防
1. 对于非富文本针对入参进行转义
可通过escapeHtml和JavaScript进行转义。
转义过后上面的代码将会变成
<span><iframe src&equalshttp&colon&sol&solhacker&periodcom><&soliframe></span>
转义后用户输入的恶意脚本代码就不会被执行从而达到了预防和修复的目的。
2. 对于富文本入参进行过滤
略。
总结
本篇简要介绍了什么是xss漏洞,xss漏洞在代码中是如何产生的,简单介绍了如何去预防和修复xss漏洞。
黑盒手动测试
对于非富文本在输入框中输入特殊字符 <”tiehua ‘> 提交
在提交后的页面查看源代码根据关键字tiehua查找源代码中的tiehua前后的<”>’是否已经被转义成
<">&apos 如果未被转义说明这个输入框存在xss漏洞的嫌疑(提交bug)。
对于富文本输入框输入<img onerror=”alert(123)” src=http://xxx.com>提交页面
如果页面有出现排版问题或者js错误说明这个输入框存在xss漏洞的嫌疑(提交bug)。
链接带参数的如:
http://mall.taobao.com/?ad_id=&am_id=&cm_id=&pm_id=
该链接包含了4个参数,对于这种的测试方法和输入框测试方法一样只不过把参数当成你的输入框进行
提交。如:
http://mall.taobao.com/?ad_id=<”tiehua’>&am_id=&cm_id=&pm_id=
另:可能大家会说光这点不足以说服开发修改bug,很可惜本文旨在说明如何找到xss漏洞并不是说明
如何利用xss漏洞,感兴趣的看情况线下交流呵呵。
黑盒工具测试
推荐工具
- Paros(免费)
- Acunetix.Web.Vulnerability.Scanner (商业工具)
白盒代码扫描测试
在上一篇中我们讲到了xss漏洞产生的代码原因和解决方法如:
<span>$!productName</span>
此类的非富文本代码我们可以强制要求规范为:
<span> $!stringEscapeUtil.escapeHtml ($!productName)</span>
对于富文本的我们可以强制要求代码规范为通过过滤层过滤。
根据以上的两条规则,我们可以从白盒代码上去进行静态扫描代码是否按照规范编写来预防和筛选xss漏洞。