The NoteBook of EricKong

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  611 Posts :: 1 Stories :: 190 Comments :: 0 Trackbacks

#

一. 目的 

本文旨在介绍如何安装OpenLDAP并且设置一个公司内部的集中化的邮件地址薄服务器供客户端查询。 
基本上,OpenLDAPg还应用在其它许多方面,象集中化的用户帐号验证服务器,但邮件地址薄查询是最常用的。 

二. 安装 

www.openldap.org下载最新的openldap软件包,按照编译和安装的步骤,依次运行:


#tar cvfz openldap-stable-20010524.tgz 
#cd openldap-2.0.11 
#./configure 
#make depend 
#make 
#make test 
#make install 

我的操作环境是redhat 6.1,如果没有遇到任何错误,最后默认安装LDAP后台程序slapd到目录/usr/local/libexec;配置文件在目录/usr/local/etc/openldap/ 并且放各种OpenLDAP工具
ldapadd,ldapdelete,ldapmodify,ldapmodrdn,ldappasswd,ldapsearch
在目录/usr/local/bin,运行时数据库在/usr/local/var/openldap-ldbm 。 


三. 设置 

1) 更改配置文件/usr/local/etc/openldap/slapd.conf 
在include /usr/local/etc/openldap/schema/core.schema这行后面加上下面的行包括所有的方案。 

include /usr/local/etc/openldap/schema/corba.schema 
include /usr/local/etc/openldap/schema/cosine.schema 
include /usr/local/etc/openldap/schema/inetorgperson.schema 
include /usr/local/etc/openldap/schema/java.schema 
include /usr/local/etc/openldap/schema/krb5-kdc.schema 
include /usr/local/etc/openldap/schema/misc.schema 
include /usr/local/etc/openldap/schema/nadf.schema 
include /usr/local/etc/openldap/schema/nis.schema 
include /usr/local/etc/openldap/schema/openldap.schema 

2) 在文件slapd.conf的"ldbm database definitions"部分更改相应的
suffix,rootdn行如下 

database ldbm 
suffix "o=yourdomain,c=us" 
rootdn "cn=root,o=yourdomain,c=us" 
rootpw secret 
directory /usr/local/var/openldap-ldbm 

有各种格式你可以用,这里我用的是o=yourdomain,c=us 说明你的公司域名和所在的国家或地区rootdn的格式安装后默认为cn=Manager,这里改为root完全是自己的喜好,这样符合Unix/Linux中root具有最高权限的传统。 

3) 现在可以启动slapd了,运行/usr/local/libexec/slapd 。 

可以考虑把/usr/local/bin and /usr/local/libexec加到搜索路径中,即加到/etc/profile中的PATH行: 
PATH="$PATH:/usr/X11R6/bin:/usr/local/bin:/usr/local/libexec" 
这样下次登录后只需键入 slapd 。 

4) 测试ldap server是否正常工作。 
运行下面的命令检查是否有相应的输出。 

#ldapsearch -x -b 'o=yourdomain,c=us' '(objectclass=*)' 


5) 编辑.ldif文本文件,用ldapadd添加记录进入LDAP数据库。 
文件内容如下: 

dn: o=yourdomain,c=us 
objectclass: dcobject 
objectclass: organization 
o: yourdomain 
dc: yourdomain 

dn: cn=Jephe Wu,o=yourdomain,c=us 
objectclass: inetorgperson 
cn: Jephe Wu 
sn: Wu 
mail: jephe_wu@yourdomain.com 


......more users...... 

依次类推,添加每个人的记录进入该文件中,注意对象类型 inetorgperson 至少必须要有cn和sn,这里我们用cn,sn,mail三项定义,这对我们的邮件地址薄功能来说已经足够。你还可以定义象mobile, homephone,pager......等等。 

然后用下面的命令添加上面的.ldif文件进入LDAP数据库 

#ldapadd -x -D "cn=root,o=yourdomain,c=us" -w secret -f
"yourldiffilename" 

注:上面的文件的第一部分"dn: o=yourdomain,c=us"是必须的,否则不能添加数据。 
用你的公司的域名替换上面的"yourdomain"。 

6) 设置Outlook Express, 允许用LDAP服务器查询邮件地址。 

"工具/帐号/添加--目录服务",填入你的服务器的IP地址或者主机全称域名,在下一个屏幕中选yes以允许用目录服务来查询地址,最后在"目录服务"栏中选中刚才设置的项目击“属性/高级",在"搜索库"中填入 
"o=yourdomain,c=us" 。 
Netscape请根据上面的信息设置相应的选项。 

四. 常见使用问题 

1) 能启动slapd 没有问题,但不能添加数据库,运行ldapadd添加时出错 "ldap_bind:cannot contact LDAP Server" 。 
答: 最可能的原因是在/etc/hosts中没有127.0.0.1 localhost项目。 

2) 注意查询顺序: 如果在Outlook Express的地址薄中有内容,则检查地址时地址薄优 先,如果在本地地址薄中找不到相应记录,然后再查询LDAP服务器。 

3) 用下面的命令确信客户端与LDAP服务器有通讯,在服务器运行下面的命令,然后在OE中测试检查地址,你将会得到查询LDAP数据库的连接过程的输出。 

# tcpdump port 389

posted @ 2013-10-31 09:34 Eric_jiang 阅读(238) | 评论 (0)编辑 收藏

import com.ibm.mq.MQC;
import com.ibm.mq.MQEnvironment;
import com.ibm.mq.MQException;
import com.ibm.mq.MQGetMessageOptions;
import com.ibm.mq.MQMessage;
import com.ibm.mq.MQPutMessageOptions;
import com.ibm.mq.MQQueue;
import com.ibm.mq.MQQueueManager;

/**//*
 * 可以在MQ的资源管理器的某一个队列上放入测试消息、浏览消息等
 * 可以放入多条消息,按先进先出的方式取得
 
*/
public class MQTest {

    
private String qManager;// QueueManager名

    
private MQQueueManager qMgr;

    
private MQQueue qQueue;

    String HOST_NAME;

    
int PORT = 0;

    String Q_NAME;

    String CHANNEL;

    
int CCSID;

    String Msg;

    
public void init() {

        
try {
            HOST_NAME 
= "192.168.88.169";
            PORT 
= 1414;
            qManager 
= "QM_yfgaochun";
            Q_NAME 
= "QM_NAME1";
            CHANNEL 
= "S_yfgaochun";
            CCSID 
= 1381
            
// 表示是简体中文,
            
// CCSID的值在AIX上一般设为1383,如果要支持GBK则设为1386,在WIN上设为1381。

            Msg 
= "MQ测试发送Gao";
            
// System.out.println(Msg);

            MQEnvironment.hostname 
= HOST_NAME; // 安裝MQ所在的ip address
            MQEnvironment.port = PORT; // TCP/IP port

            MQEnvironment.channel 
= CHANNEL;
            MQEnvironment.CCSID 
= CCSID;

            qMgr 
= new MQQueueManager(qManager);

         
            
int qOptioin = MQC.MQOO_INPUT_AS_Q_DEF | MQC.MQOO_INQUIRE
                    
| MQC.MQOO_OUTPUT;

            qQueue 
= qMgr.accessQueue(Q_NAME, qOptioin);

        } 
catch (MQException e) {
            System.out
                    .println(
"A WebSphere MQ error occurred : Completion code "
                            
+ e.completionCode + " Reason Code is "
                            
+ e.reasonCode);
        }
    }

    
void finalizer() {
        
try {
            qQueue.close();
            qMgr.disconnect();
        } 
catch (MQException e) {
            System.out
                    .println(
"A WebSphere MQ error occurred : Completion code "
                            
+ e.completionCode + " Reason Code is "
                            
+ e.reasonCode);
        }
    }

    
/**//*
         * 取过一次,下次就没有了
         
*/
    
public void GetMsg() {
        
try {
            MQMessage retrievedMessage 
= new MQMessage();

            MQGetMessageOptions gmo 
= new MQGetMessageOptions();
            gmo.options 
+= MQC.MQPMO_SYNCPOINT;

            qQueue.get(retrievedMessage, gmo);

            
int length = retrievedMessage.getDataLength();

            
byte[] msg = new byte[length];

            retrievedMessage.readFully(msg);

            String sMsg 
= new String(msg);
            System.out.println(sMsg);

        } 
catch (RuntimeException e) {
            e.printStackTrace();
        } 
catch (MQException e) {
            
if (e.reasonCode != 2033// 没有消息
            {
                e.printStackTrace();
                System.out
                        .println(
"A WebSphere MQ error occurred : Completion code "
                                
+ e.completionCode
                                
+ " Reason Code is "
                                
+ e.reasonCode);
            }
        } 
catch (java.io.IOException e) {
            System.out
                    .println(
"An error occurred whilst to the message buffer "
                            
+ e);
        }
    }

    
public void SendMsg(byte[] qByte) {
        
try {
            MQMessage qMsg 
= new MQMessage();
            qMsg.write(qByte);
            MQPutMessageOptions pmo 
= new MQPutMessageOptions();

            qQueue.put(qMsg, pmo);

            System.out.println(
"The message is sent!");
            System.out.println(
"\tThe message is " + new String(qByte, "GBK"));
        } 
catch (MQException e) {
            System.out
                    .println(
"A WebSphere MQ error occurred : Completion code "
                            
+ e.completionCode + " Reason Code is "
                            
+ e.reasonCode);
        } 
catch (java.io.IOException e) {
            System.out
                    .println(
"An error occurred whilst to the message buffer "
                            
+ e);
        }

    }

    
/** */
    
/**
     * 
@param args
     
*/
    
public static void main(String[] args) {
        
// TODO Auto-generated method stub
        MQTest mqst = new MQTest();
        mqst.init();
        
try {
            mqst.SendMsg(mqst.Msg.getBytes(
"GBK"));
            
// mqst.GetMsg();
        } catch (Exception e) {
            e.printStackTrace();
        }
        mqst.finalizer();
    }

}
posted @ 2013-10-24 17:08 Eric_jiang 阅读(571) | 评论 (1)编辑 收藏

/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/ (多行注释)
//[^\r\n]*+ (单行注释)
\”[^\\\\\"]*(?:\\\\.[^\\\\\"]*)*\” (双引号字符串)
‘[^\\\\']*(?:\\\\.[^\\\\']*)*’ (单引号字符串)
posted @ 2013-10-22 15:55 Eric_jiang 阅读(496) | 评论 (0)编辑 收藏

在客户端编程语言中,如JavaScript和ActionScript,同源策略是一个很重要的安全理念,它在保证数据的安全性方面有着重要的意义。同 源策略规定跨域之间的脚本是隔离的,一个域的脚本不能访问和操作另外一个域的绝大部分属性和方法。那么什么叫相同域,什么叫不同的域呢?

同源策略

在客户端编程语言中,如JavaScript和ActionScript,同源策略是一个很重要的安全理念,它在保证数据的安全性方面有着重要的意义。同源策略规定跨域之间的脚本是隔离的,一个域的脚本不能访问和操作另外一个域的绝大部分属性和方法

那么什么叫相同域,什么叫不同的域呢?当两个域具有相同的协议(如http), 相同的端口(如80),相同的host(如www.example.org),那么我们就可以认为它们是相同的域。比如http://www.example.org/和http://www.example.org/sub/是同域,而http://www.example.org, https://www.example.org, http://www.example.org:8080, http://sub.example.org中的任何两个都将构成跨域。同源策略还应该对一些特殊情况做处理,比如限制file协议下脚本的访问权限。本地的HTML文件在浏览器中是通过file协议打开的,如果脚本能通过file协议访问到硬盘上其它任意文件,就会出现安全隐患,目前IE8还有这样的隐患。

受到同源策略的影响,跨域资源共享就会受到制约。但是随着人们的实践和浏览器的进步,目前在跨域请求的技巧上,有很多宝贵经验的沉淀和积累。这里我把跨域资源共享分成两种,一种是单向的数据请求,还有一种是双向的消息通信。接下来我将罗列出常见的一些跨域方式,以下跨域实例的源代码可以从这里获得。

单向跨域

JSONP

JSONP (JSON with Padding)是一个简单高效的跨域方式,HTML中的script标签可以加载并执行其他域的JavaScript,于是我们可以通过script标记来动态加载其他域的资源。例如我要从域A的页面pageA加载域B的数据,那么在域B的页面pageB中我以JavaScript的形式声明pageA需要的数据,然后在pageA中用script标签把pageB加载进来,那么pageB中的脚本就会得以执行。JSONP在此基础上加入了回调函数,pageB加载完之后会执行pageA中定义的函数,所需要的数据会以参数的形式传递给该函数。JSONP易于实现,但是也会存在一些安全隐患,如果第三方的脚本随意地执行,那么它就可以篡改页面内容,截获敏感数据。但是在受信任的双方传递数据,JSONP是非常合适的选择。

Flash URLLoader

Flash有自己的一套安全策略,服务器可以通过crossdomain.xml文件来声明能被哪些域的SWF文件访问,SWF也可以通过API来确定自身能被哪些域的SWF加载。当跨域访问资源时,例如从域www.a.com请求域www.b.com上的数据,我们可以借助Flash来发送HTTP请求。首先,修改域www.b.com上的crossdomain.xml(一般存放在根目录,如果没有需要手动创建) ,把www.a.com加入到白名单。其次,通过Flash URLLoader发送HTTP请求,最后,通过Flash API把响应结果传递给JavaScript。Flash URLLoader是一种很普遍的跨域解决方案,不过需要支持iOS的话,这个方案就无能为力了。

Access Control

Access Control是比较超越的跨域方式,目前只在很少的浏览器中得以支持,这些浏览器可以发送一个跨域的HTTP请求(Firefox, Google Chrome等通过XMLHTTPRequest实现,IE8下通过XDomainRequest实现),请求的响应必须包含一个Access-Control-Allow-Origin的HTTP响应头,该响应头声明了请求域的可访问权限。例如www.a.com对www.b.com下的asset.php发送了一个跨域的HTTP请求,那么asset.php必须加入如下的响应头:

header("Access-Control-Allow-Origin: http://www.a.com"); 		

window.name

window对象的name属性是一个很特别的属性,当该window的location变化,然后重新加载,它的name属性可以依然保持不变。那么我们可以在页面A中用iframe加载其他域的页面B,而页面B中用JavaScript把需要传递的数据赋值给window.name,iframe加载完成之后,页面A修改iframe的地址,将其变成同域的一个地址,然后就可以读出window.name的值了。这个方式非常适合单向的数据请求,而且协议简单、安全。不会像JSONP那样不做限制地执行外部脚本。

server proxy

在数据提供方没有提供对JSONP协议或者window.name协议的支持,也没有对其它域开放访问权限时,我们可以通过server proxy的方式来抓取数据。例如当www.a.com域下的页面需要请求www.b.com下的资源文件asset.txt时,直接发送一个指向www.b.com/asset.txt的ajax请求肯定是会被浏览器阻止。这时,我们在www.a.com下配一个代理,然后把ajax请求绑定到这个代理路径下,例如www.a.com/proxy/, 然后这个代理发送HTTP请求访问www.b.com下的asset.txt,跨域的HTTP请求是在服务器端进行的,客户端并没有产生跨域的ajax请求。这个跨域方式不需要和目标资源签订协议,带有侵略性,另外需要注意的是实践中应该对这个代理实施一定程度的保护,比如限制他人使用或者使用频率。

双向跨域

document.domain

通过修改document的domain属性,我们可以在域和子域或者不同的子域之间通信。同域策略认为域和子域隶属于不同的域,比如www.a.com和sub.a.com是不同的域,这时,我们无法在www.a.com下的页面中调用sub.a.com中定义的JavaScript方法。但是当我们把它们document的domain属性都修改为a.com,浏览器就会认为它们处于同一个域下,那么我们就可以互相调用对方的method来通信了。

FIM – Fragment Identitier Messaging

不同的域之间,JavaScript只能做很有限的访问和操作,其实我们利用这些有限的访问权限就可以达到跨域通信的目的了。FIM (Fragment Identitier Messaging)就是在这个大前提下被发明的。父窗口可以对iframe进行URL读写,iframe也可以读写父窗口的URL,URL有一部分被称为frag,就是#号及其后面的字符,它一般用于浏览器锚点定位,Server端并不关心这部分,应该说HTTP请求过程中不会携带frag,所以这部分的修改不会产生HTTP请求,但是会产生浏览器历史记录。FIM的原理就是改变URL的frag部分来进行双向通信。每个window通过改变其他window的location来发送消息,并通过监听自己的URL的变化来接收消息。这个方式的通信会造成一些不必要的浏览器历史记录,而且有些浏览器不支持onhashchange事件,需要轮询来获知URL的改变,最后,URL在浏览器下有长度限制,这个制约了每次传送的数据量。

Flash LocalConnection

页面上的双向通信也可以通过Flash来解决,Flash API中有LocalConnection这个类,该类允许两个SWF之间通过进程通信,这时SWF可以播放在独立的Flash Player或者AIR中,也可以嵌在HTML页面或者是PDF中。遵循这个通信原则,我们可以在不同域的HTML页面各自嵌套一个SWF来达到相互传递数据的目的了。SWF通过LocalConnection交换数据是很快的,但是每次的数据量有40kb的大小限制。用这种方式来跨域通信过于复杂,而且需要了2个SWF文件,实用性不强。

window.postMessage

window.postMessage是HTML5定义的一个很新的方法,这个方法可以很方便地跨window通信。由于它是一个很新的方法,所以在很旧和比较旧的浏览器中都无法使用。

Cross Frame

Cross Frame是FIM的一个变种,它借助了一个空白的iframe,不会产生多余的浏览器历史记录,也不需要轮询URL的改变,在可用性和性能上都做了很大的改观。它的基本原理大致是这样的,假设在域www.a.com上有页面A.html和一个空白代理页面proxyA.html, 另一个域www.b.com上有个页面B.html和一个空白代理页面proxyB.html,A.html需要向B.html中发送消息时,页面会创建一个隐藏的iframe, iframe的src指向proxyB.html并把message作为URL frag,由于B.html和proxyB.html是同域,所以在iframe加载完成之后,B.html可以获得iframe的URL,然后解析出message,并移除该iframe。当B.html需要向A.html发送消息时,原理一样。Cross Frame是很好的双向通信方式,而且安全高效,但是它在Opera中无法使用,不过在Opera下面我们可以使用更简单的window.postMessage来代替。

总结

跨域的方法很多,不同的应用场景我们都可以找到一个最合适的解决方案。比如单向的数据请求,我们应该优先选择JSONP或者window.name,双向通信我们采取Cross Frame,在未与数据提供方没有达成通信协议的情况下我们也可以用server proxy的方式来抓取数据。

posted @ 2013-10-08 13:13 Eric_jiang 阅读(269) | 评论 (0)编辑 收藏

事件就是用户或者浏览器自身执行的某种动作。诸如click、load、和scroll等等,都是事件的名字。而响应某个事件的函就叫做事件处理程序(或事件侦听器)。事件处理程序的名字都是以”on“开头,因此ckick事件的事件处理程序就是onclick,load的事件处理程序就是onload。

页面中添加事件的有几种方式

  1. 直接将代码写在HTMl上

    <div onclick="alert('Hello World');">Nowamagic</div>

    代码少的还勉强可以,代码多的话就哭了写页面的哥们了。

  2. 定义一个函数,分配给html元素

    <script type="text/javascript"> function clk(){} </script> //..... <div onclick="clk()">Div2 Element</div>

    这样做虽然能减少html代码上的js量,但是这样子做有几个缺点:用户可能在HTMl代码已经出现在页面上,但是js事件函数可能还没加载进来的情况下就点击了事件对象元素,从而导致错误;还有就是HTML与javascript代码还是未分离完全,如果要修改就要改HTML代码和javascript代码两处

  3. HTML与javascript代码完全分离

    document.getElementById('myButton').onclick = function(){     alert('Hello!'); } <div id="myButton">点击按钮/div>

    它只需要HTML元素提供一个id属性(或其它能获取该元素对象的方式),就可以实现事件的注册。真正做到HTML与javascript代码完全分离,结构与行为完全分离的事件处理方法。

如何监听事件

DOM Leavl 0

DOM Leavl 0是最早的事件处理形式,它既可以直接写在HTMl上,也可以把一个函数分配给一个事件处理程序。然而,这种方式给一个元素的同一事件只允许一个处理器。因此,我们还要继续完善。

W3C DOM Leavl 2 – 事件监听器

通过W3C DEMO Leavl 2事件处理,我们不会直接把一个函数分配给一个事件处理程序;相反,我们将新函数添加一个事件监听器:

var el = document.getElementById('myButton') el.addEventListener( 'click', function(){     alert('Hello!'); }, false)
targetElement.addEventlistener(typeOfEvent,listenerFunction,useCapture);
W3C DOM Leaval 2通用语法

尽管这个方法看起来比之前那个方法复杂了一点,但是那些额外的代码还是有必要打出来的。对于DOM级别2的事件最大的好处就是一个事件可以注册许多处理器。

addEventlistener的头两个参数是目标对象和事件,不仅如此,函数最后一个参数,可以指定处理器是在捕获阶段还是冒泡阶段被触发(通过设置”addEventListener()”函数的第三个参数来指定 – true表示在捕获阶段,false表示在冒泡阶段)

接下来将针对W3C DOM Leavl 2事件进行讨论。

事件在文档中被传递的两种模型

W3C DOM Leavl 2事件流包括三个阶段:事件捕获阶段、处于目标简短和事件冒泡阶段。

首先我们了解下事件冒泡和事件捕获。

事件冒泡

在页面上有多个事件,也可以多个元素响应同一个事件。假设网页上有两个元素,其中一个元素嵌套在另一个元素中,并且都被绑定了 click 事件,同时 body 也绑定了 click 事件,如下:

js代码如下:

window.onload = function(){ var oBubble = document.getElementById("oBubble"); var oBubble1 = document.getElementById("oBubble1"); var oBubble2 = document.getElementById("oBubble2"); oBubble.onclick = function(){ alert("Bubble") } oBubble1.onclick = function(){ alert("Bubble1") } oBubble2.onclick = function(){ alert("Bubble2") } }

html代码如下:

<body id="oBubble">//点击#oBubble弹出Bubble     <div id="oBubble1">//点击#oBubble1先后弹出Bubble1、Bubble         <span id="oBubble2">oBubble</span>//点击#oBubble2先后弹出Bubble2 、Bubble1、Bubble     </div> </body>

事件顺序:span→div→body,如下图所示:

JavaScript欲速则不达——基本处理事件详解和阻止事件传播
事件冒泡实例图例

很明显,每个元素都会按照(inside→outside)的冒泡型事件,所以事件冒泡会引起预料之外的效果。事件冒泡是IE-DOM处理事件对象的方法。

事件捕获

事件捕获和事件冒泡是刚好相反的两个过程,事件捕获是按照(outside→inside)的冒泡型事件开始触发。因此拿以上冒泡例子,alert信息是跟事件冒泡完全相反的顺序。

一些注意事项:

  1. W3C DOM Leavl 2标准的addEventListener方法执行事件的顺序是按照事件注册的顺序执行的。而IE的attachEvent方法则相反–后注册的事件先觖发,先注册的事件后触发。
  2. W3C DOM Leavl 2标准的浏览器文本节点也会冒泡,而IE内核的浏览器文本节点不会冒泡。
  3. W3C DOM Leavl 2浏览器事件对象与IE内核的浏览器事件不同(具体请参阅)。
  4. DOM标准的浏览器事件卸载方式与IE内核的事件卸载方式不同。

接下来我们就来解决跨浏览器的事件处理的方案。

跨浏览器的事件处理函数

前面我们介绍了事件冒泡和事件捕获两种事件事件获取方式,而W3C模型 是两者中和。就是事件发生时,先从顶层开始进行事件捕获,直到事件触发到达了事件源元素。然后,再从事件源往上进行事件冒泡,直到到达document。

利用W3C DOM Leavl 2事件监听器,就是 addEventListener函数。我们可以自己选择绑定事件时采用事件捕获还是事件冒泡,方法就是绑定事件时通过addEventListener函数,上面我们介绍过它的三个参数了:如果第三个参数若是true,则表示采用事件捕获,若是false,则表示采用事件冒泡。

但是在一个支持W3C DOM的浏览器中,按照DOM Leavl 1绑定事件方式,采用的全都是事件冒泡方式。大多数时候,我们也是希望事件从内部嵌套的的元素冒泡到外围元素。

解决方案

以上我们介绍过 W3C DOM Leaval 2事件绑定中的addEventlistener,可以为元素添加多个事件,而且最后一个参数还支持事件冒泡或捕获,IE6/7/8仍然没有遵循标准而使用了自己专有的attachEvent,且不支持事件捕获,所有事件都是发生在冒泡阶段。

所以创建一个可重用。实现了DOM Leavl 2事件处理的事件处理函数,但是,它还是要跨浏览器。如下经典代码

listenEvent函数代码

function listenEvent(eventTarget, eventType, evrntHandler) { if (eventTarget.addEventListener){         eventTarget.addEventListener(eventType, evrntHandler, true);//IE9等其他现代浏览器 } else if (eventTarget.attachEvent){         eventType = "on"+eventType;         eventTarget.attachEvent(eventType,evrntHandler) //IE6、7、8 } else {eventTarget["on" + eventType] = evrntHandler;}//IE5~ 个人觉得不写也罢。 }

listenEvent函数使用

listenEventdocument,"click",processClick
可重用的事件处理函数

此处理函数接受3个函数:目标对象、事件(作为一个字符串),以及函数名称。首先测试对象,看看它是否支持addEventListener(W3C DOM Leaval 2的事件监听方法),如果支持这个方法,就把事件映射到事件处理函数。回到代码,因为IE6、7、8不支持addEventListener,所以检查是否支持attachEvent,记得前面加”on“,因为不加”on“只是事件的名字,但是因为IE6、7、8只支持向上冒泡,所以此方案中 addEventListener的第三个参数是false。最后为了兼容DOM leaval 0事件处理,还要加最后一行代码。

使用W3C DOM Leavl 2处理事件事件监听不会有覆盖之前绑定事件的现象,每个绑定的事件都会被执行,不过 attachEvent 为元素增加的一系列事件不是以添加它们顺序执行的,而是以相反的顺序触发。最重要的是,采用事件监听给对象绑定方法后,可以解除相应的绑定。跟以上代码类似,removeEventListener跟addEventListener对应,detachEvent跟eventType对应,得到如下解决方案:

stopListening函数代码

function stopListening(eventTarget, eventType, evrntHandler) { if (eventTarget.removeEventListener){         eventTarget.removeEventListener(eventType, evrntHandler, true);//IE9等其他现代浏览器 } else if (eventTarget.attachEvent){         detachEvent = "on"+eventType;         eventTarget.detachEvent(eventType,evrntHandler) //IE6、7、8 } else {eventTarget["on" + eventType] = null;}//IE5~ }
stopListeningdocument,"click",processClick
可重用的事件处理函数

在DOM标准的事件卸载方式中需要注意的是:事件捕获的参数。如果你的事件是注册在捕获阶段,则卸载事件时,必须将其指定为捕获阶段(true),否则无法卸载;如果你的事件注册在注册在冒泡阶段,则必须将其指定为冒泡阶段(false),否则同样无法卸载。

现在,如果我们想停止监听一个事件,可以直接调用stopListening,同样传入3个参数:目标对象、事件和事件处理函数。

阻止冒泡

因为大部分浏览器都是按照DOM Leavl 1绑定事件方式,采用的全都是事件冒泡方式。所以阻止事件冒泡(嵌套元素中传播)是很有必要的。如下方案:

阻止冒泡方案:

function cancelPropagation (event){ event = window.event||event; if( document.all){ event.cancelBubble = true; }else{ event.stopPropagation(); } }

stopListening函数使用

//这里我们采用上面介绍过的事件处理函数 listenEvent 函数 listenEvent(document.getElementById("oBubble2"),"click",function(evt){     cancelPropagation(evt); })
阻止冒泡

因为IE8、7、6不支持W3C DOM Leavel 2不支持,那么我们就设置event.cancelBubble 的属性值为 true;而支持其他现代浏览器则使用W3C DOM Leavel 2的,则调用stopPropagation方法。

最后罗列文章中出现的几个Event方法

  1. W3C DOM Leavl 2绑定和解除事件的方法:addEventListener和removeEventListener:
  2. IE绑定和解除事件的方法:attachEvent和detachEvent
  3. 取消事件:W3C DOM Leavl 2使用preventDefault(),iE直接返回false
  4. 阻止事件在嵌套函数中传播(阻止冒泡和捕获):W3C DOM Leavl 2使用stopPropagation(),IE中cancelBubble返回true

本文出现所有DEMO下载:js-attachEvent.rar

posted @ 2013-10-08 13:12 Eric_jiang 阅读(6525) | 评论 (0)编辑 收藏

在做AJAX应用开发的时候,我们通常喜欢把服务器端返回的JSON格式字符串在客户端的回调函数中把它作为JavaScript代码执行并用一个变量保存起来,以方便使用返回的数据。通常的做法就是var jsonData = eval(xmlHttp.responseText)。这看起来似乎一切都是正确的,但当你运行代码的时候,你会发现报“invalid labe”错误了。为什么?我也不清楚,但我找到了解决这个问题的方法。

在我刚遇到这个问题的时候也特别头痛,因为看起来所有编码是正确的,为了测试出现问题的位置,我逐渐缩小代码范围,最终得到如下简短代码:

var jsonStr1 = '{"Name":"Tom","Sex":"Man"}';
var jsonObj1 = eval(jsonStr1);
alert(jsonObj1.Name);

以上代码执行正是报一开始说的invalid labe错误。难道eval函数对某些表达式或对象有限制?于是我又测试了数组对象,代码如下,结果下面代码运行很正常:

var arrStr = '["Tom","Man"]';
var arrObj = eval(arrStr);
alert(arrObj[
0]);

难道是我机子上的JavaScript解析器就JSON解析方面出了问题,于是我又测试下面代码,但结果一样正常:

var jsonObj = {"Name":"Tom","Sex":"Man"};
alert(jsonObj.Name);

最终我还是没有自行把问题解决,于是根据相关错误信息上网搜索答案,没想到一下子就找到了问题的根源,解决办法就是“在eval的时候,要先把 JSON字符串值用 ‘()’括号先括起来”。网上找的资料都没有说明是什么原因,当然我也还是没有明白正真的原因的。括号是起强制先执行或先运算作用的,返回的JSON就一个完整的对象,中间也没有表达式,为什么还要加括号!像数组这种较复杂点的对象也能正常eval。没办法,就先记着这种用法吧。正确用法如下(注意看eval两端的括号):

var jsonStr2 = '{"Name":"Tom","Sex":"Man"}';
var jsonObj2 = eval('(' + jsonStr2 + ')');
alert(jsonObj2.Name);

posted @ 2013-10-08 12:56 Eric_jiang 阅读(373) | 评论 (0)编辑 收藏

一、什么是事件冒泡
在一个对象上触发某类事件(比如单击onclick事件),如果此对象定义了此事件的处理程序,那么此事件就会调用这个处理程序,如果没有定义此事件处理程序或者事件返回true,那么这个事件会向这个对象的父级对象传播,从里到外,直至它被处理(父级对象所有同类事件都将被激活),或者它到达了对象层次的最顶层,即document对象(有些浏览器是window)。
打个比方说:你在地方法院要上诉一件案子,如果地方没有处理此类案件的法院,地方相关部门会帮你继续往上级法院上诉,比如从市级到省级,直至到中央法院,最终使你的案件得以处理。
二、事件冒泡有什么作用
(1)事件冒泡允许多个操作被集中处理(把事件处理器添加到一个父级元素上,避免把事件处理器添加到多个子级元素上),它还可以让你在对象层的不同级别捕获事件。
【集中处理例子】
<div onclick="eventHandle(event)" id="outSide" style="width:100px; height:100px; background:#000; padding:50px">
<div id="inSide" style="width:100px; height:100px; background:#CCC"></div>
</div>
<script type="text/javascript">
//本例子只在外面盒子定义了处理方法,而这个方法一样可以捕获到子元素点击行为并处理它。假设有成千上万子元素要处理,难道我们要为每个元素加“onclick="eventHandle(event)"”?显然没有这种集中处理的方法来的简单,同时它的性能也是更高的。
function eventHandle(e)
{
    var e=e||window.event;
    var obj=e.target||e.srcElement;
    alert(obj.id+' was click')
}
</script>
2)让不同的对象同时捕获同一事件,并调用自己的专属处理程序做自己的事情,就像老板一下命令,各自员工做自己岗位上的工作去了。
【同时捕获同一事件例子】
<div onclick="outSideWork()" id="outSide" style="width:100px; height:100px; background:#000; padding:50px">
<div onclick="inSideWork()" id="inSide" style="width:100px; height:100px; background:#CCC"></div>
</div>
<script type="text/javascript">
function outSideWork()
{
    alert('My name is outSide,I was working...');
}
function inSideWork()
{
    alert('My name is inSide,I was working...');
}
//因为下面程序自动激活单击事件,有些浏览器不允许,所以请单击灰色盒子,从这里开始下命令,这样因为冒泡的原因,黑色大盒子也会收到单击事件,并调用了自己的处理程序。如果还有更多盒子嵌套,一样道理。
/*
function bossOrder()
{
    document.getElmentById('inSide').click();
}
bossOrder();
*/
</script>
三、需要注意什么
●事件捕获其实有三种方式,事件冒泡只是其中的一种:(1)IE从里到外(inside→outside)的冒泡型事件。(2)Netscape4.0从外到里(outside→inside)的捕获型事件。(3)DOM事件流,先从外到里,再从里到外回到原点(outside→inside→outside)的事件捕获方法(似乎对象将触发两次事件处理,这有什么作用?鄙人不懂!)。
●不是所有的事件都能冒泡。以下事件不冒泡:blur、focus、load、unload。
●事件捕获方式在不同浏览器,甚至同种浏览器的不同版本中是有所区别的。如Netscape4.0采用捕获型事件解决方案,其它多数浏览器则支持冒泡型事件解决方案,另外DOM事件流还支持文本节点事件冒泡。
●事件捕获到达顶层的目标在不同浏览器或不同浏览器版本也是有区别的。在IE6中HTML是接收事件冒泡的,另外大部分浏览器将冒泡延续到window对象,即……body→documen→window。
●阻止冒泡并不能阻止对象默认行为。比如submit按钮被点击后会提交表单数据,这种行为无须我们写程序定制。
四、阻止事件冒泡
通常情况下我们都是一步到位,明确自己的事件触发源,并不希望浏览器自作聪明、漫无目的地去帮我们找合适的事件处理程序,即我们明确最精准目标,这种情况下我们不需要事件冒泡。另外通过对事件冒泡的理解,我们知道程序将做多较多额外的事情,这必然增大程序开销。还有一个重要的问题是:事件冒泡处理可能会激活我们本来不想激活的事件,导致程序错乱,甚至无从下手调试,这常成为对事件冒泡不熟悉程序员的棘手问题。所以必要时,我们要阻止事件冒泡。
【不想激活的事件被激活例子】
<div onclick="openWin('http://www.baidu.com')" id="outSide" style="width:100px; height:100px; background:#000; padding:50px">
<div onclick="openWin('http://www.google.com')" id="inSide" style="width:100px; height:100px; background:#CCC"></div>
</div>
<script type="text/javascript">
//本例你实际希望点击灰色盒子打开google首页,而点击黑色盒子打开baidu首页,但结果你点击灰色盒子的时候,却是同时打开了两个网页。其实在实际设计中较少遇到此问题,你可能会想如果我在页面不同DOM深处安置了不同的按钮或链接,深层处的事件触发会不会波及顶层的按钮呢?不会,因为按钮不能形成嵌套关系。
function openWin(url)
{
    window.open(url);
}
</script>
下面是本人在网上抄的一个方法,把这个方法放在精准目标对象处理程序结尾,本事件触发处理结束后,事件将不在进行冒泡处理。
【阻止事件冒泡例子】
<div onclick="showMsg(this,event)" id="outSide" style="width:100px; height:100px; background:#000; padding:50px">
<div onclick="showMsg(this,event)" id="inSide" style="width:100px; height:100px; background:#CCC"></div>
</div>
<script type="text/javascript">
//阻止事件冒泡后,你点击灰色盒子,整个过程只弹一次对话框了(注意与默认情况对比)
function showMsg(obj,e)
{
    alert(obj.id);
    stopBubble(e)
}
//阻止事件冒泡函数
function stopBubble(e)
{
    if (e && e.stopPropagation)
        e.stopPropagation()
    else
        window.event.cancelBubble=true
}
</script>
posted @ 2013-10-08 12:50 Eric_jiang 阅读(211) | 评论 (0)编辑 收藏

1.查询Oracle所有系统权限 
 
select * from system_privilege_map   
2.查询Oracle所有对象权限 
 
select * from table_privilege_map   
3.将'授予系统权限'这个权限给某用户--当然一般采用 dba 给其他用户授予“其他权限”,这个权限一般不需要给别人 
 
grant any privilege to TestUser 【with admin option】//表示 TestUser 用户有权利 给其他用户授予 系统权限 。后面 表示对这个权限的维护(能否再授予其他用户)   
4.举例: 授予系统权限 create session (连接数据库的关键权限,connect角色中有这个权限,oracle角色 文章中有介绍) 
 
1.grant create session to TestUser //TestUser就可以连接数据库了  
2.grant create session to TestUser with option admin //TestUser就可以连接数据库了,并且 可以 将这个权限 给其他用户  
5.收回 系统权限 不会级联回收 
 
revoke create session from TestUser  
6.关于 系统权限 的维护 
 
with admin option //表示继承后可以 授予其他用户  
7.关于 对象权限 的维护 
 
with grant option //表示继承后可以 授予其他用户  
8.举例: 授予对象权限 update,select,insert,delete,all [4种等于 all] 
 
grant select on scott.emp to TestUser 【with grant option】 //表示给TestUser 授予scott.emp的查询权限  
grant all on scott.emp to TestUser //表示给TestUser 授予scott.emp的select,update,insert,delete 权限  
9.举例: 授予 某几列 对象权限 
 
grant update on scott.emp(sal) to luob //指定修改某列  
grant select on emp(ename,sal) to luob //只能查询这指定字段  
10.举例:授予 alter 权限 
 
grant alter on scott.emp to luob //授予这个表结构的修改权限  
11.举例:授予 execute 权限 (用于用户执行其他方案的包、过程,函数) 
 
grant execute on dbms_transaction to luob; --执行 dbms_transaction 包的权限  
12.举例:授予 index 权限 
 
grant index on scott.emp to luob 【with grant option】 //授予创建索引的权限  
13.收回 对象权限 【cascade】会级联回收 
 
revoke select on scott.emp from TestUser【cascade】//撤销查询权限或者级联撤销  
14.举例:级联回收的 
 
grant select on emp to luobing with grant option; //授予权限 并维护  
conn luobin/m123@ORACLE; //登录后 给 xiaoming 权限  
grant select on emp to xiaoming;  
conn scott/tiger@ORACLE //scott 撤销 luobing的权限  
revoke select on emp from luobing cascade  
conn xiaoming/m123@ORACLE;  
select * from scott.emp; //表和视图不存在  
15.查询当前用户具有的系统权限 
 
select * from dba_sys_privs where grantee='SYSTEM'  
16.查询当前用户具有的对象权限 
 
select * from dba_tab_privs where grantee='SYSTEM';  
17.查询当前用户具有的列权限 
 
select * from dba_col_privs where grantee='SYSTEM';  
18.查询用户 SCOTT 所拥有的系统权限 
 
select * from dba_sys_privs where grantee in (select granted_role from dba_role_privs where grantee='SCOTT');  
19.数据库管理员 DBA的一些职责 
 
1.安装和升级 oracle 数据库  
2.建库建表建空间 视图,索引。。。。  
3.指定和并实施 备份和恢复计划  
4.数据库权限管理,调优,故障排除  
5.对高级的dba,要求能参加项目开发,会编写sql语句 ,存储过程,触发器,规则,约束,包  
6.管理员 还有管理初始化参数  
     show  parameter; 有 200多参数 有参数可以配置的  
7.管理数据库的用户主要是 sys (董事长)> 和system  (总经理)  
20.sys,sysdba,sysoper的区别 
 
sys:拥有oracle的基表和视图,拥有 dba 数据库管理  
sysdba:系统管理员  
sysoper:系统操作员  的角色和权限  
system:主要存储次一级的数据 如:oracle的特性和工具的管理信息和   
dba,sysdba 角色权限 区别     
1.存储的数据重要性不一样 ,权限不一样   
2.sys 必须 利用 as sysdba 或者 as sysoper 不能用normal(标准)方式登录  
3.system 默认登录角色是  dba   (conn system/manager)  
4.如果用  conn system/manager as sysdba  登录结果和 sys 登录一样  
21. sysdba 和 sysoper的权限区别 
权限sysdbasysoper
能够 Startup/Shutdown 启动/关闭数据库yy
alter database open/mount/backup(设置数据库不同的状态)yy
改变字符集yn
采用 create/drop database(创建/删除数据库)yn
create spfileyy
alter database archivelog(归档日志)yy
alter database recover(完全和部分恢复数据库)y只能完全恢复,不能执行部分恢复
拥有 restricted session(会话限制)权限yy
可以让用户作为sys 用户连接yy
登录之后syspublic
posted @ 2013-10-08 11:51 Eric_jiang 阅读(234) | 评论 (0)编辑 收藏

我们将从创建Oracle用户权限表开始谈起,然后讲解登陆等一般性动作,使大家对Oracle用户权限表有个深入的了解。

  一、创建

  sys;//系统管理员,拥有最高权限

  system;//本地管理员,次高权限

  scott;//普通用户,密码默认为tiger,默认未解锁

  sys;//系统管理员,拥有最高权限

  system;//本地管理员,次高权限

  scott;//普通用户,密码默认为tiger,默认未解锁

  二、登陆

  sqlplus / as sysdba;//登陆sys帐户

  sqlplus sys as sysdba;//同上

  sqlplus scott/tiger;//登陆普通用户scott

  sqlplus / as sysdba;//登陆sys帐户

  sqlplus sys as sysdba;//同上

  sqlplus scott/tiger;//登陆普通用户scott

  三、管理用户

  create user zhangsan;//在管理员帐户下,创建用户zhangsan

  alert user scott identified by tiger;//修改密码

  create user zhangsan;//在管理员帐户下,创建用户zhangsan

  alert user scott identified by tiger;//修改密码

  四,授予权限

  1、默认的普通用户scott默认未解锁,不能进行那个使用,新建的用户也没有任何权限,必须授予权限

  /*管理员授权*/

  grant create session to zhangsan;//授予zhangsan用户创建session的权限,即登陆权限

  grant unlimited session to zhangsan;//授予zhangsan用户使用表空间的权限

  grant create table to zhangsan;//授予创建表的权限

  grante drop table to zhangsan;//授予删除表的权限

  grant insert table to zhangsan;//插入表的权限

  grant update table to zhangsan;//修改表的权限

  grant all to public;//这条比较重要,授予所有权限(all)给所有用户(public)

  /*管理员授权*/

  grant create session to zhangsan;//授予zhangsan用户创建session的权限,即登陆权限

  grant unlimited session to zhangsan;//授予zhangsan用户使用表空间的权限

  grant create table to zhangsan;//授予创建表的权限

  grante drop table to zhangsan;//授予删除表的权限

  grant insert table to zhangsan;//插入表的权限

  grant update table to zhangsan;//修改表的权限

  grant all to public;//这条比较重要,授予所有权限(all)给所有用户(public)

  2、oralce对权限管理比较严谨,普通用户之间也是默认不能互相访问的,需要互相授权

  /*oralce对权限管理比较严谨,普通用户之间也是默认不能互相访问的*/

  grant select on tablename to zhangsan;//授予zhangsan用户查看指定表的权限

  grant drop on tablename to zhangsan;//授予删除表的权限

  grant insert on tablename to zhangsan;//授予插入的权限

  grant update on tablename to zhangsan;//授予修改表的权限

  grant insert(id) on tablename to zhangsan;

  grant update(id) on tablename to zhangsan;//授予对指定表特定字段的插入和修改权限,注意,只能是insert和update

  grant alert all table to zhangsan;//授予zhangsan用户alert任意表的权限

  /*oralce对权限管理比较严谨,普通用户之间也是默认不能互相访问的*/

  grant select on tablename to zhangsan;//授予zhangsan用户查看指定表的权限

  grant drop on tablename to zhangsan;//授予删除表的权限

  grant insert on tablename to zhangsan;//授予插入的权限

  grant update on tablename to zhangsan;//授予修改表的权限

  grant insert(id) on tablename to zhangsan;

  grant update(id) on tablename to zhangsan;//授予对指定表特定字段的插入和修改权限,注意,只能是insert和update

  grant alert all table to zhangsan;//授予zhangsan用户alert任意表的权限

  五、撤销权限

  基本语法同grant,关键字为revoke

  基本语法同grant,关键字为revoke

  六、查看权限

  select * from user_sys_privs;//查看当前用户所有权限

  select * from user_tab_privs;//查看所用用户对表的权限

  select * from user_sys_privs;//查看当前用户所有权限

  select * from user_tab_privs;//查看所用用户对表的权限

  七、操作表的用户的表

  /*需要在表名前加上用户名,如下*/

  select * from zhangsan.tablename

  /*需要在表名前加上用户名,如下*/

  select * from zhangsan.tablename

  八、权限传递

  即用户A将权限授予B,B可以将操作的权限再授予C,命令如下:

  grant alert table on tablename to zhangsan with admin option;//关键字 with admin option

  grant alert table on tablename to zhangsan with grant option;//关键字 with grant option效果和admin类似

  grant alert table on tablename to zhangsan with admin option;//关键字 with admin option

  grant alert table on tablename to zhangsan with grant option;//关键字 with grant option效果和admin类似

  九、角色

  角色即权限的集合,可以把一个角色授予给用户

  create role myrole;//创建角色

  grant create session to myrole;//将创建session的权限授予myrole

  grant myrole to zhangsan;//授予zhangsan用户myrole的角色

  drop role myrole;删除角色

  /*但是有些权限是不能授予给角色的,比如unlimited tablespace和any关键字*/

  Oracle用户权限表就介绍到这里。

posted @ 2013-10-08 11:44 Eric_jiang 阅读(197) | 评论 (0)编辑 收藏

JavaScript中的String是只读的,所以每次对String变量的操作都会在内存中产生一个零时变量,如果要对字符串进行大量的重复操作,性能和效率都会很低下,因此常用数组的方法操作字符串,即先把字符串都存储在数组中,然后使用join()方法连接字符串。
当然可以把这种方法再演变一下,在JavaScript中模拟StringBuffer类。
<script type="text/javascript">
    function StringBuffer(){
        this._Strings = new Array();
    }
    StringBuffer.prototype = {
        append : function(str){
            this._Strings.push(str);
        },
        toString : function(){
            return this._Strings.join(",");
        }
    }
    
    var myvar = new StringBuffer();
    myvar.append("a");
    myvar.append("b");
    myvar.append("c");
    myvar.append("d");
    myvar.append("e");
    alert(myvar.toString());
</script>
可以把这种方法和原始的直接操作String的方法进行对比,会发现效率提高了很多。(注意:要在IE里面进行比较,在firefox里的效率是差不多的)
posted @ 2013-10-08 09:50 Eric_jiang 阅读(354) | 评论 (0)编辑 收藏

仅列出标题
共57页: First 上一页 15 16 17 18 19 20 21 22 23 下一页 Last