The NoteBook of EricKong

            BlogJava :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理
            611 Posts :: 1 Stories :: 190 Comments :: 0 Trackbacks

          #

          一. 目的 

          本文旨在介紹如何安裝OpenLDAP并且設(shè)置一個(gè)公司內(nèi)部的集中化的郵件地址薄服務(wù)器供客戶端查詢。 
          基本上,OpenLDAPg還應(yīng)用在其它許多方面,象集中化的用戶帳號(hào)驗(yàn)證服務(wù)器,但郵件地址薄查詢是最常用的。 

          二. 安裝 

          www.openldap.org下載最新的openldap軟件包,按照編譯和安裝的步驟,依次運(yùn)行:


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

          我的操作環(huán)境是redhat 6.1,如果沒(méi)有遇到任何錯(cuò)誤,最后默認(rèn)安裝LDAP后臺(tái)程序slapd到目錄/usr/local/libexec;配置文件在目錄/usr/local/etc/openldap/ 并且放各種OpenLDAP工具
          ldapadd,ldapdelete,ldapmodify,ldapmodrdn,ldappasswd,ldapsearch
          在目錄/usr/local/bin,運(yùn)行時(shí)數(shù)據(jù)庫(kù)在/usr/local/var/openldap-ldbm 。 


          三. 設(shè)置 

          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"部分更改相應(yīng)的
          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 說(shuō)明你的公司域名和所在的國(guó)家或地區(qū)rootdn的格式安裝后默認(rèn)為cn=Manager,這里改為root完全是自己的喜好,這樣符合Unix/Linux中root具有最高權(quán)限的傳統(tǒng)。 

          3) 現(xiàn)在可以啟動(dòng)slapd了,運(yùn)行/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) 測(cè)試ldap server是否正常工作。 
          運(yùn)行下面的命令檢查是否有相應(yīng)的輸出。 

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


          5) 編輯.ldif文本文件,用ldapadd添加記錄進(jìn)入LDAP數(shù)據(jù)庫(kù)。 
          文件內(nèi)容如下: 

          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...... 

          依次類推,添加每個(gè)人的記錄進(jìn)入該文件中,注意對(duì)象類型 inetorgperson 至少必須要有cn和sn,這里我們用cn,sn,mail三項(xiàng)定義,這對(duì)我們的郵件地址薄功能來(lái)說(shuō)已經(jīng)足夠。你還可以定義象mobile, homephone,pager......等等。 

          然后用下面的命令添加上面的.ldif文件進(jìn)入LDAP數(shù)據(jù)庫(kù) 

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

          注:上面的文件的第一部分"dn: o=yourdomain,c=us"是必須的,否則不能添加數(shù)據(jù)。 
          用你的公司的域名替換上面的"yourdomain"。 

          6) 設(shè)置Outlook Express, 允許用LDAP服務(wù)器查詢郵件地址。 

          "工具/帳號(hào)/添加--目錄服務(wù)",填入你的服務(wù)器的IP地址或者主機(jī)全稱域名,在下一個(gè)屏幕中選yes以允許用目錄服務(wù)來(lái)查詢地址,最后在"目錄服務(wù)"欄中選中剛才設(shè)置的項(xiàng)目擊“屬性/高級(jí)",在"搜索庫(kù)"中填入 
          "o=yourdomain,c=us" 。 
          Netscape請(qǐng)根據(jù)上面的信息設(shè)置相應(yīng)的選項(xiàng)。 

          四. 常見(jiàn)使用問(wèn)題 

          1) 能啟動(dòng)slapd 沒(méi)有問(wèn)題,但不能添加數(shù)據(jù)庫(kù),運(yùn)行l(wèi)dapadd添加時(shí)出錯(cuò) "ldap_bind:cannot contact LDAP Server" 。 
          答: 最可能的原因是在/etc/hosts中沒(méi)有127.0.0.1 localhost項(xiàng)目。 

          2) 注意查詢順序: 如果在Outlook Express的地址薄中有內(nèi)容,則檢查地址時(shí)地址薄優(yōu) 先,如果在本地地址薄中找不到相應(yīng)記錄,然后再查詢LDAP服務(wù)器。 

          3) 用下面的命令確信客戶端與LDAP服務(wù)器有通訊,在服務(wù)器運(yùn)行下面的命令,然后在OE中測(cè)試檢查地址,你將會(huì)得到查詢LDAP數(shù)據(jù)庫(kù)的連接過(guò)程的輸出。 

          # tcpdump port 389

          posted @ 2013-10-31 09:34 Eric_jiang 閱讀(244) | 評(píng)論 (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的資源管理器的某一個(gè)隊(duì)列上放入測(cè)試消息、瀏覽消息等
           * 可以放入多條消息,按先進(jìn)先出的方式取得
           
          */
          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
                      
          // 表示是簡(jiǎn)體中文,
                      
          // CCSID的值在AIX上一般設(shè)為1383,如果要支持GBK則設(shè)為1386,在WIN上設(shè)為1381。

                      Msg 
          = "MQ測(cè)試發(fā)送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);
                  }
              }

              
          /**//*
                   * 取過(guò)一次,下次就沒(méi)有了
                   
          */
              
          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// 沒(méi)有消息
                      {
                          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 閱讀(575) | 評(píng)論 (1)編輯 收藏

          /\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/ (多行注釋)
          //[^\r\n]*+ (單行注釋)
          \”[^\\\\\"]*(?:\\\\.[^\\\\\"]*)*\” (雙引號(hào)字符串)
          ‘[^\\\\']*(?:\\\\.[^\\\\']*)*’ (單引號(hào)字符串)
          posted @ 2013-10-22 15:55 Eric_jiang 閱讀(503) | 評(píng)論 (0)編輯 收藏

          在客戶端編程語(yǔ)言中,如JavaScript和ActionScript,同源策略是一個(gè)很重要的安全理念,它在保證數(shù)據(jù)的安全性方面有著重要的意義。同 源策略規(guī)定跨域之間的腳本是隔離的,一個(gè)域的腳本不能訪問(wèn)和操作另外一個(gè)域的絕大部分屬性和方法。那么什么叫相同域,什么叫不同的域呢?

          同源策略

          在客戶端編程語(yǔ)言中,如JavaScript和ActionScript,同源策略是一個(gè)很重要的安全理念,它在保證數(shù)據(jù)的安全性方面有著重要的意義。同源策略規(guī)定跨域之間的腳本是隔離的,一個(gè)域的腳本不能訪問(wèn)和操作另外一個(gè)域的絕大部分屬性和方法

          那么什么叫相同域,什么叫不同的域呢?當(dāng)兩個(gè)域具有相同的協(xié)議(如http), 相同的端口(如80),相同的host(如www.example.org),那么我們就可以認(rèn)為它們是相同的域。比如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中的任何兩個(gè)都將構(gòu)成跨域。同源策略還應(yīng)該對(duì)一些特殊情況做處理,比如限制file協(xié)議下腳本的訪問(wèn)權(quán)限。本地的HTML文件在瀏覽器中是通過(guò)file協(xié)議打開(kāi)的,如果腳本能通過(guò)file協(xié)議訪問(wèn)到硬盤上其它任意文件,就會(huì)出現(xiàn)安全隱患,目前IE8還有這樣的隱患。

          受到同源策略的影響,跨域資源共享就會(huì)受到制約。但是隨著人們的實(shí)踐和瀏覽器的進(jìn)步,目前在跨域請(qǐng)求的技巧上,有很多寶貴經(jīng)驗(yàn)的沉淀和積累。這里我把跨域資源共享分成兩種,一種是單向的數(shù)據(jù)請(qǐng)求,還有一種是雙向的消息通信。接下來(lái)我將羅列出常見(jiàn)的一些跨域方式,以下跨域?qū)嵗脑创a可以從這里獲得。

          單向跨域

          JSONP

          JSONP (JSON with Padding)是一個(gè)簡(jiǎn)單高效的跨域方式,HTML中的script標(biāo)簽可以加載并執(zhí)行其他域的JavaScript,于是我們可以通過(guò)script標(biāo)記來(lái)動(dòng)態(tài)加載其他域的資源。例如我要從域A的頁(yè)面pageA加載域B的數(shù)據(jù),那么在域B的頁(yè)面pageB中我以JavaScript的形式聲明pageA需要的數(shù)據(jù),然后在pageA中用script標(biāo)簽把pageB加載進(jìn)來(lái),那么pageB中的腳本就會(huì)得以執(zhí)行。JSONP在此基礎(chǔ)上加入了回調(diào)函數(shù),pageB加載完之后會(huì)執(zhí)行pageA中定義的函數(shù),所需要的數(shù)據(jù)會(huì)以參數(shù)的形式傳遞給該函數(shù)。JSONP易于實(shí)現(xiàn),但是也會(huì)存在一些安全隱患,如果第三方的腳本隨意地執(zhí)行,那么它就可以篡改頁(yè)面內(nèi)容,截獲敏感數(shù)據(jù)。但是在受信任的雙方傳遞數(shù)據(jù),JSONP是非常合適的選擇。

          Flash URLLoader

          Flash有自己的一套安全策略,服務(wù)器可以通過(guò)crossdomain.xml文件來(lái)聲明能被哪些域的SWF文件訪問(wèn),SWF也可以通過(guò)API來(lái)確定自身能被哪些域的SWF加載。當(dāng)跨域訪問(wèn)資源時(shí),例如從域www.a.com請(qǐng)求域www.b.com上的數(shù)據(jù),我們可以借助Flash來(lái)發(fā)送HTTP請(qǐng)求。首先,修改域www.b.com上的crossdomain.xml(一般存放在根目錄,如果沒(méi)有需要手動(dòng)創(chuàng)建) ,把www.a.com加入到白名單。其次,通過(guò)Flash URLLoader發(fā)送HTTP請(qǐng)求,最后,通過(guò)Flash API把響應(yīng)結(jié)果傳遞給JavaScript。Flash URLLoader是一種很普遍的跨域解決方案,不過(guò)需要支持iOS的話,這個(gè)方案就無(wú)能為力了。

          Access Control

          Access Control是比較超越的跨域方式,目前只在很少的瀏覽器中得以支持,這些瀏覽器可以發(fā)送一個(gè)跨域的HTTP請(qǐng)求(Firefox, Google Chrome等通過(guò)XMLHTTPRequest實(shí)現(xiàn),IE8下通過(guò)XDomainRequest實(shí)現(xiàn)),請(qǐng)求的響應(yīng)必須包含一個(gè)Access-Control-Allow-Origin的HTTP響應(yīng)頭,該響應(yīng)頭聲明了請(qǐng)求域的可訪問(wèn)權(quán)限。例如www.a.com對(duì)www.b.com下的asset.php發(fā)送了一個(gè)跨域的HTTP請(qǐng)求,那么asset.php必須加入如下的響應(yīng)頭:

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

          window.name

          window對(duì)象的name屬性是一個(gè)很特別的屬性,當(dāng)該window的location變化,然后重新加載,它的name屬性可以依然保持不變。那么我們可以在頁(yè)面A中用iframe加載其他域的頁(yè)面B,而頁(yè)面B中用JavaScript把需要傳遞的數(shù)據(jù)賦值給window.name,iframe加載完成之后,頁(yè)面A修改iframe的地址,將其變成同域的一個(gè)地址,然后就可以讀出window.name的值了。這個(gè)方式非常適合單向的數(shù)據(jù)請(qǐng)求,而且協(xié)議簡(jiǎn)單、安全。不會(huì)像JSONP那樣不做限制地執(zhí)行外部腳本。

          server proxy

          在數(shù)據(jù)提供方?jīng)]有提供對(duì)JSONP協(xié)議或者window.name協(xié)議的支持,也沒(méi)有對(duì)其它域開(kāi)放訪問(wèn)權(quán)限時(shí),我們可以通過(guò)server proxy的方式來(lái)抓取數(shù)據(jù)。例如當(dāng)www.a.com域下的頁(yè)面需要請(qǐng)求www.b.com下的資源文件asset.txt時(shí),直接發(fā)送一個(gè)指向www.b.com/asset.txt的ajax請(qǐng)求肯定是會(huì)被瀏覽器阻止。這時(shí),我們?cè)趙ww.a.com下配一個(gè)代理,然后把a(bǔ)jax請(qǐng)求綁定到這個(gè)代理路徑下,例如www.a.com/proxy/, 然后這個(gè)代理發(fā)送HTTP請(qǐng)求訪問(wèn)www.b.com下的asset.txt,跨域的HTTP請(qǐng)求是在服務(wù)器端進(jìn)行的,客戶端并沒(méi)有產(chǎn)生跨域的ajax請(qǐng)求。這個(gè)跨域方式不需要和目標(biāo)資源簽訂協(xié)議,帶有侵略性,另外需要注意的是實(shí)踐中應(yīng)該對(duì)這個(gè)代理實(shí)施一定程度的保護(hù),比如限制他人使用或者使用頻率。

          雙向跨域

          document.domain

          通過(guò)修改document的domain屬性,我們可以在域和子域或者不同的子域之間通信。同域策略認(rèn)為域和子域隸屬于不同的域,比如www.a.com和sub.a.com是不同的域,這時(shí),我們無(wú)法在www.a.com下的頁(yè)面中調(diào)用sub.a.com中定義的JavaScript方法。但是當(dāng)我們把它們document的domain屬性都修改為a.com,瀏覽器就會(huì)認(rèn)為它們處于同一個(gè)域下,那么我們就可以互相調(diào)用對(duì)方的method來(lái)通信了。

          FIM – Fragment Identitier Messaging

          不同的域之間,JavaScript只能做很有限的訪問(wèn)和操作,其實(shí)我們利用這些有限的訪問(wèn)權(quán)限就可以達(dá)到跨域通信的目的了。FIM (Fragment Identitier Messaging)就是在這個(gè)大前提下被發(fā)明的。父窗口可以對(duì)iframe進(jìn)行URL讀寫,iframe也可以讀寫父窗口的URL,URL有一部分被稱為frag,就是#號(hào)及其后面的字符,它一般用于瀏覽器錨點(diǎn)定位,Server端并不關(guān)心這部分,應(yīng)該說(shuō)HTTP請(qǐng)求過(guò)程中不會(huì)攜帶frag,所以這部分的修改不會(huì)產(chǎn)生HTTP請(qǐng)求,但是會(huì)產(chǎn)生瀏覽器歷史記錄。FIM的原理就是改變URL的frag部分來(lái)進(jìn)行雙向通信。每個(gè)window通過(guò)改變其他window的location來(lái)發(fā)送消息,并通過(guò)監(jiān)聽(tīng)自己的URL的變化來(lái)接收消息。這個(gè)方式的通信會(huì)造成一些不必要的瀏覽器歷史記錄,而且有些瀏覽器不支持onhashchange事件,需要輪詢來(lái)獲知URL的改變,最后,URL在瀏覽器下有長(zhǎng)度限制,這個(gè)制約了每次傳送的數(shù)據(jù)量。

          Flash LocalConnection

          頁(yè)面上的雙向通信也可以通過(guò)Flash來(lái)解決,F(xiàn)lash API中有LocalConnection這個(gè)類,該類允許兩個(gè)SWF之間通過(guò)進(jìn)程通信,這時(shí)SWF可以播放在獨(dú)立的Flash Player或者AIR中,也可以嵌在HTML頁(yè)面或者是PDF中。遵循這個(gè)通信原則,我們可以在不同域的HTML頁(yè)面各自嵌套一個(gè)SWF來(lái)達(dá)到相互傳遞數(shù)據(jù)的目的了。SWF通過(guò)LocalConnection交換數(shù)據(jù)是很快的,但是每次的數(shù)據(jù)量有40kb的大小限制。用這種方式來(lái)跨域通信過(guò)于復(fù)雜,而且需要了2個(gè)SWF文件,實(shí)用性不強(qiáng)。

          window.postMessage

          window.postMessage是HTML5定義的一個(gè)很新的方法,這個(gè)方法可以很方便地跨window通信。由于它是一個(gè)很新的方法,所以在很舊和比較舊的瀏覽器中都無(wú)法使用。

          Cross Frame

          Cross Frame是FIM的一個(gè)變種,它借助了一個(gè)空白的iframe,不會(huì)產(chǎn)生多余的瀏覽器歷史記錄,也不需要輪詢URL的改變,在可用性和性能上都做了很大的改觀。它的基本原理大致是這樣的,假設(shè)在域www.a.com上有頁(yè)面A.html和一個(gè)空白代理頁(yè)面proxyA.html, 另一個(gè)域www.b.com上有個(gè)頁(yè)面B.html和一個(gè)空白代理頁(yè)面proxyB.html,A.html需要向B.html中發(fā)送消息時(shí),頁(yè)面會(huì)創(chuàng)建一個(gè)隱藏的iframe, iframe的src指向proxyB.html并把message作為URL frag,由于B.html和proxyB.html是同域,所以在iframe加載完成之后,B.html可以獲得iframe的URL,然后解析出message,并移除該iframe。當(dāng)B.html需要向A.html發(fā)送消息時(shí),原理一樣。Cross Frame是很好的雙向通信方式,而且安全高效,但是它在Opera中無(wú)法使用,不過(guò)在Opera下面我們可以使用更簡(jiǎn)單的window.postMessage來(lái)代替。

          總結(jié)

          跨域的方法很多,不同的應(yīng)用場(chǎng)景我們都可以找到一個(gè)最合適的解決方案。比如單向的數(shù)據(jù)請(qǐng)求,我們應(yīng)該優(yōu)先選擇JSONP或者window.name,雙向通信我們采取Cross Frame,在未與數(shù)據(jù)提供方?jīng)]有達(dá)成通信協(xié)議的情況下我們也可以用server proxy的方式來(lái)抓取數(shù)據(jù)。

          posted @ 2013-10-08 13:13 Eric_jiang 閱讀(282) | 評(píng)論 (0)編輯 收藏

          事件就是用戶或者瀏覽器自身執(zhí)行的某種動(dòng)作。諸如click、load、和scroll等等,都是事件的名字。而響應(yīng)某個(gè)事件的函就叫做事件處理程序(或事件偵聽(tīng)器)。事件處理程序的名字都是以”on“開(kāi)頭,因此ckick事件的事件處理程序就是onclick,load的事件處理程序就是onload。

          頁(yè)面中添加事件的有幾種方式

          1. 直接將代碼寫在HTMl上

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

            代碼少的還勉強(qiáng)可以,代碼多的話就哭了寫頁(yè)面的哥們了。

          2. 定義一個(gè)函數(shù),分配給html元素

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

            這樣做雖然能減少html代碼上的js量,但是這樣子做有幾個(gè)缺點(diǎn):用戶可能在HTMl代碼已經(jīng)出現(xiàn)在頁(yè)面上,但是js事件函數(shù)可能還沒(méi)加載進(jìn)來(lái)的情況下就點(diǎn)擊了事件對(duì)象元素,從而導(dǎo)致錯(cuò)誤;還有就是HTML與javascript代碼還是未分離完全,如果要修改就要改HTML代碼和javascript代碼兩處

          3. HTML與javascript代碼完全分離

            document.getElementById('myButton').onclick = function(){     alert('Hello!'); } <div id="myButton">點(diǎn)擊按鈕/div>

            它只需要HTML元素提供一個(gè)id屬性(或其它能獲取該元素對(duì)象的方式),就可以實(shí)現(xiàn)事件的注冊(cè)。真正做到HTML與javascript代碼完全分離,結(jié)構(gòu)與行為完全分離的事件處理方法。

          如何監(jiān)聽(tīng)事件

          DOM Leavl 0

          DOM Leavl 0是最早的事件處理形式,它既可以直接寫在HTMl上,也可以把一個(gè)函數(shù)分配給一個(gè)事件處理程序。然而,這種方式給一個(gè)元素的同一事件只允許一個(gè)處理器。因此,我們還要繼續(xù)完善。

          W3C DOM Leavl 2 – 事件監(jiān)聽(tīng)器

          通過(guò)W3C DEMO Leavl 2事件處理,我們不會(huì)直接把一個(gè)函數(shù)分配給一個(gè)事件處理程序;相反,我們將新函數(shù)添加一個(gè)事件監(jiān)聽(tīng)器:

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

          盡管這個(gè)方法看起來(lái)比之前那個(gè)方法復(fù)雜了一點(diǎn),但是那些額外的代碼還是有必要打出來(lái)的。對(duì)于DOM級(jí)別2的事件最大的好處就是一個(gè)事件可以注冊(cè)許多處理器。

          addEventlistener的頭兩個(gè)參數(shù)是目標(biāo)對(duì)象和事件,不僅如此,函數(shù)最后一個(gè)參數(shù),可以指定處理器是在捕獲階段還是冒泡階段被觸發(fā)(通過(guò)設(shè)置”addEventListener()”函數(shù)的第三個(gè)參數(shù)來(lái)指定 – true表示在捕獲階段,false表示在冒泡階段)

          接下來(lái)將針對(duì)W3C DOM Leavl 2事件進(jìn)行討論。

          事件在文檔中被傳遞的兩種模型

          W3C DOM Leavl 2事件流包括三個(gè)階段:事件捕獲階段、處于目標(biāo)簡(jiǎn)短和事件冒泡階段。

          首先我們了解下事件冒泡和事件捕獲。

          事件冒泡

          在頁(yè)面上有多個(gè)事件,也可以多個(gè)元素響應(yīng)同一個(gè)事件。假設(shè)網(wǎng)頁(yè)上有兩個(gè)元素,其中一個(gè)元素嵌套在另一個(gè)元素中,并且都被綁定了 click 事件,同時(shí) 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">//點(diǎn)擊#oBubble彈出Bubble     <div id="oBubble1">//點(diǎn)擊#oBubble1先后彈出Bubble1、Bubble         <span id="oBubble2">oBubble</span>//點(diǎn)擊#oBubble2先后彈出Bubble2 、Bubble1、Bubble     </div> </body>

          事件順序:span→div→body,如下圖所示:

          JavaScript欲速則不達(dá)——基本處理事件詳解和阻止事件傳播
          事件冒泡實(shí)例圖例

          很明顯,每個(gè)元素都會(huì)按照(inside→outside)的冒泡型事件,所以事件冒泡會(huì)引起預(yù)料之外的效果。事件冒泡是IE-DOM處理事件對(duì)象的方法。

          事件捕獲

          事件捕獲和事件冒泡是剛好相反的兩個(gè)過(guò)程,事件捕獲是按照(outside→inside)的冒泡型事件開(kāi)始觸發(fā)。因此拿以上冒泡例子,alert信息是跟事件冒泡完全相反的順序。

          一些注意事項(xiàng):

          1. W3C DOM Leavl 2標(biāo)準(zhǔn)的addEventListener方法執(zhí)行事件的順序是按照事件注冊(cè)的順序執(zhí)行的。而IE的attachEvent方法則相反–后注冊(cè)的事件先觖發(fā),先注冊(cè)的事件后觸發(fā)。
          2. W3C DOM Leavl 2標(biāo)準(zhǔn)的瀏覽器文本節(jié)點(diǎn)也會(huì)冒泡,而IE內(nèi)核的瀏覽器文本節(jié)點(diǎn)不會(huì)冒泡。
          3. W3C DOM Leavl 2瀏覽器事件對(duì)象與IE內(nèi)核的瀏覽器事件不同(具體請(qǐng)參閱)。
          4. DOM標(biāo)準(zhǔn)的瀏覽器事件卸載方式與IE內(nèi)核的事件卸載方式不同。

          接下來(lái)我們就來(lái)解決跨瀏覽器的事件處理的方案。

          跨瀏覽器的事件處理函數(shù)

          前面我們介紹了事件冒泡和事件捕獲兩種事件事件獲取方式,而W3C模型 是兩者中和。就是事件發(fā)生時(shí),先從頂層開(kāi)始進(jìn)行事件捕獲,直到事件觸發(fā)到達(dá)了事件源元素。然后,再?gòu)氖录赐线M(jìn)行事件冒泡,直到到達(dá)document。

          利用W3C DOM Leavl 2事件監(jiān)聽(tīng)器,就是 addEventListener函數(shù)。我們可以自己選擇綁定事件時(shí)采用事件捕獲還是事件冒泡,方法就是綁定事件時(shí)通過(guò)addEventListener函數(shù),上面我們介紹過(guò)它的三個(gè)參數(shù)了:如果第三個(gè)參數(shù)若是true,則表示采用事件捕獲,若是false,則表示采用事件冒泡。

          但是在一個(gè)支持W3C DOM的瀏覽器中,按照DOM Leavl 1綁定事件方式,采用的全都是事件冒泡方式。大多數(shù)時(shí)候,我們也是希望事件從內(nèi)部嵌套的的元素冒泡到外圍元素。

          解決方案

          以上我們介紹過(guò) W3C DOM Leaval 2事件綁定中的addEventlistener,可以為元素添加多個(gè)事件,而且最后一個(gè)參數(shù)還支持事件冒泡或捕獲,IE6/7/8仍然沒(méi)有遵循標(biāo)準(zhǔn)而使用了自己專有的attachEvent,且不支持事件捕獲,所有事件都是發(fā)生在冒泡階段。

          所以創(chuàng)建一個(gè)可重用。實(shí)現(xiàn)了DOM Leavl 2事件處理的事件處理函數(shù),但是,它還是要跨瀏覽器。如下經(jīng)典代碼

          listenEvent函數(shù)代碼

          function listenEvent(eventTarget, eventType, evrntHandler) { if (eventTarget.addEventListener){         eventTarget.addEventListener(eventType, evrntHandler, true);//IE9等其他現(xiàn)代瀏覽器 } else if (eventTarget.attachEvent){         eventType = "on"+eventType;         eventTarget.attachEvent(eventType,evrntHandler) //IE6、7、8 } else {eventTarget["on" + eventType] = evrntHandler;}//IE5~ 個(gè)人覺(jué)得不寫也罷。 }

          listenEvent函數(shù)使用

          listenEventdocument,"click",processClick
          可重用的事件處理函數(shù)

          此處理函數(shù)接受3個(gè)函數(shù):目標(biāo)對(duì)象、事件(作為一個(gè)字符串),以及函數(shù)名稱。首先測(cè)試對(duì)象,看看它是否支持addEventListener(W3C DOM Leaval 2的事件監(jiān)聽(tīng)方法),如果支持這個(gè)方法,就把事件映射到事件處理函數(shù)。回到代碼,因?yàn)镮E6、7、8不支持addEventListener,所以檢查是否支持attachEvent,記得前面加”on“,因?yàn)椴患?#8221;on“只是事件的名字,但是因?yàn)镮E6、7、8只支持向上冒泡,所以此方案中 addEventListener的第三個(gè)參數(shù)是false。最后為了兼容DOM leaval 0事件處理,還要加最后一行代碼。

          使用W3C DOM Leavl 2處理事件事件監(jiān)聽(tīng)不會(huì)有覆蓋之前綁定事件的現(xiàn)象,每個(gè)綁定的事件都會(huì)被執(zhí)行,不過(guò) attachEvent 為元素增加的一系列事件不是以添加它們順序執(zhí)行的,而是以相反的順序觸發(fā)。最重要的是,采用事件監(jiān)聽(tīng)給對(duì)象綁定方法后,可以解除相應(yīng)的綁定。跟以上代碼類似,removeEventListener跟addEventListener對(duì)應(yīng),detachEvent跟eventType對(duì)應(yīng),得到如下解決方案:

          stopListening函數(shù)代碼

          function stopListening(eventTarget, eventType, evrntHandler) { if (eventTarget.removeEventListener){         eventTarget.removeEventListener(eventType, evrntHandler, true);//IE9等其他現(xiàn)代瀏覽器 } else if (eventTarget.attachEvent){         detachEvent = "on"+eventType;         eventTarget.detachEvent(eventType,evrntHandler) //IE6、7、8 } else {eventTarget["on" + eventType] = null;}//IE5~ }
          stopListeningdocument,"click",processClick
          可重用的事件處理函數(shù)

          在DOM標(biāo)準(zhǔn)的事件卸載方式中需要注意的是:事件捕獲的參數(shù)。如果你的事件是注冊(cè)在捕獲階段,則卸載事件時(shí),必須將其指定為捕獲階段(true),否則無(wú)法卸載;如果你的事件注冊(cè)在注冊(cè)在冒泡階段,則必須將其指定為冒泡階段(false),否則同樣無(wú)法卸載。

          現(xiàn)在,如果我們想停止監(jiān)聽(tīng)一個(gè)事件,可以直接調(diào)用stopListening,同樣傳入3個(gè)參數(shù):目標(biāo)對(duì)象、事件和事件處理函數(shù)。

          阻止冒泡

          因?yàn)榇蟛糠譃g覽器都是按照DOM Leavl 1綁定事件方式,采用的全都是事件冒泡方式。所以阻止事件冒泡(嵌套元素中傳播)是很有必要的。如下方案:

          阻止冒泡方案:

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

          stopListening函數(shù)使用

          //這里我們采用上面介紹過(guò)的事件處理函數(shù) listenEvent 函數(shù) listenEvent(document.getElementById("oBubble2"),"click",function(evt){     cancelPropagation(evt); })
          阻止冒泡

          因?yàn)镮E8、7、6不支持W3C DOM Leavel 2不支持,那么我們就設(shè)置event.cancelBubble 的屬性值為 true;而支持其他現(xiàn)代瀏覽器則使用W3C DOM Leavel 2的,則調(diào)用stopPropagation方法。

          最后羅列文章中出現(xiàn)的幾個(gè)Event方法

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

          本文出現(xiàn)所有DEMO下載:js-attachEvent.rar

          posted @ 2013-10-08 13:12 Eric_jiang 閱讀(6540) | 評(píng)論 (0)編輯 收藏

          在做AJAX應(yīng)用開(kāi)發(fā)的時(shí)候,我們通常喜歡把服務(wù)器端返回的JSON格式字符串在客戶端的回調(diào)函數(shù)中把它作為JavaScript代碼執(zhí)行并用一個(gè)變量保存起來(lái),以方便使用返回的數(shù)據(jù)。通常的做法就是var jsonData = eval(xmlHttp.responseText)。這看起來(lái)似乎一切都是正確的,但當(dāng)你運(yùn)行代碼的時(shí)候,你會(huì)發(fā)現(xiàn)報(bào)“invalid labe”錯(cuò)誤了。為什么?我也不清楚,但我找到了解決這個(gè)問(wèn)題的方法。

          在我剛遇到這個(gè)問(wèn)題的時(shí)候也特別頭痛,因?yàn)榭雌饋?lái)所有編碼是正確的,為了測(cè)試出現(xiàn)問(wèn)題的位置,我逐漸縮小代碼范圍,最終得到如下簡(jiǎn)短代碼:

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

          以上代碼執(zhí)行正是報(bào)一開(kāi)始說(shuō)的invalid labe錯(cuò)誤。難道eval函數(shù)對(duì)某些表達(dá)式或?qū)ο笥邢拗疲坑谑俏矣譁y(cè)試了數(shù)組對(duì)象,代碼如下,結(jié)果下面代碼運(yùn)行很正常:

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

          難道是我機(jī)子上的JavaScript解析器就JSON解析方面出了問(wèn)題,于是我又測(cè)試下面代碼,但結(jié)果一樣正常:

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

          最終我還是沒(méi)有自行把問(wèn)題解決,于是根據(jù)相關(guān)錯(cuò)誤信息上網(wǎng)搜索答案,沒(méi)想到一下子就找到了問(wèn)題的根源,解決辦法就是“在eval的時(shí)候,要先把 JSON字符串值用 ‘()’括號(hào)先括起來(lái)”。網(wǎng)上找的資料都沒(méi)有說(shuō)明是什么原因,當(dāng)然我也還是沒(méi)有明白正真的原因的。括號(hào)是起強(qiáng)制先執(zhí)行或先運(yùn)算作用的,返回的JSON就一個(gè)完整的對(duì)象,中間也沒(méi)有表達(dá)式,為什么還要加括號(hào)!像數(shù)組這種較復(fù)雜點(diǎn)的對(duì)象也能正常eval。沒(méi)辦法,就先記著這種用法吧。正確用法如下(注意看eval兩端的括號(hào)):

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

          posted @ 2013-10-08 12:56 Eric_jiang 閱讀(385) | 評(píng)論 (0)編輯 收藏

          一、什么是事件冒泡
          在一個(gè)對(duì)象上觸發(fā)某類事件(比如單擊onclick事件),如果此對(duì)象定義了此事件的處理程序,那么此事件就會(huì)調(diào)用這個(gè)處理程序,如果沒(méi)有定義此事件處理程序或者事件返回true,那么這個(gè)事件會(huì)向這個(gè)對(duì)象的父級(jí)對(duì)象傳播,從里到外,直至它被處理(父級(jí)對(duì)象所有同類事件都將被激活),或者它到達(dá)了對(duì)象層次的最頂層,即document對(duì)象(有些瀏覽器是window)。
          打個(gè)比方說(shuō):你在地方法院要上訴一件案子,如果地方?jīng)]有處理此類案件的法院,地方相關(guān)部門會(huì)幫你繼續(xù)往上級(jí)法院上訴,比如從市級(jí)到省級(jí),直至到中央法院,最終使你的案件得以處理。
          二、事件冒泡有什么作用
          (1)事件冒泡允許多個(gè)操作被集中處理(把事件處理器添加到一個(gè)父級(jí)元素上,避免把事件處理器添加到多個(gè)子級(jí)元素上),它還可以讓你在對(duì)象層的不同級(jí)別捕獲事件。
          【集中處理例子】
          <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">
          //本例子只在外面盒子定義了處理方法,而這個(gè)方法一樣可以捕獲到子元素點(diǎn)擊行為并處理它。假設(shè)有成千上萬(wàn)子元素要處理,難道我們要為每個(gè)元素加“onclick="eventHandle(event)"”?顯然沒(méi)有這種集中處理的方法來(lái)的簡(jiǎn)單,同時(shí)它的性能也是更高的。
          function eventHandle(e)
          {
              var e=e||window.event;
              var obj=e.target||e.srcElement;
              alert(obj.id+' was click')
          }
          </script>
          2)讓不同的對(duì)象同時(shí)捕獲同一事件,并調(diào)用自己的專屬處理程序做自己的事情,就像老板一下命令,各自員工做自己崗位上的工作去了。
          【同時(shí)捕獲同一事件例子】
          <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...');
          }
          //因?yàn)橄旅娉绦蜃詣?dòng)激活單擊事件,有些瀏覽器不允許,所以請(qǐng)單擊灰色盒子,從這里開(kāi)始下命令,這樣因?yàn)槊芭莸脑颍谏蠛凶右矔?huì)收到單擊事件,并調(diào)用了自己的處理程序。如果還有更多盒子嵌套,一樣道理。
          /*
          function bossOrder()
          {
              document.getElmentById('inSide').click();
          }
          bossOrder();
          */
          </script>
          三、需要注意什么
          ●事件捕獲其實(shí)有三種方式,事件冒泡只是其中的一種:(1)IE從里到外(inside→outside)的冒泡型事件。(2)Netscape4.0從外到里(outside→inside)的捕獲型事件。(3)DOM事件流,先從外到里,再?gòu)睦锏酵饣氐皆c(diǎn)(outside→inside→outside)的事件捕獲方法(似乎對(duì)象將觸發(fā)兩次事件處理,這有什么作用?鄙人不懂!)。
          ●不是所有的事件都能冒泡。以下事件不冒泡:blur、focus、load、unload。
          ●事件捕獲方式在不同瀏覽器,甚至同種瀏覽器的不同版本中是有所區(qū)別的。如Netscape4.0采用捕獲型事件解決方案,其它多數(shù)瀏覽器則支持冒泡型事件解決方案,另外DOM事件流還支持文本節(jié)點(diǎn)事件冒泡。
          ●事件捕獲到達(dá)頂層的目標(biāo)在不同瀏覽器或不同瀏覽器版本也是有區(qū)別的。在IE6中HTML是接收事件冒泡的,另外大部分瀏覽器將冒泡延續(xù)到window對(duì)象,即……body→documen→window。
          ●阻止冒泡并不能阻止對(duì)象默認(rèn)行為。比如submit按鈕被點(diǎn)擊后會(huì)提交表單數(shù)據(jù),這種行為無(wú)須我們寫程序定制。
          四、阻止事件冒泡
          通常情況下我們都是一步到位,明確自己的事件觸發(fā)源,并不希望瀏覽器自作聰明、漫無(wú)目的地去幫我們找合適的事件處理程序,即我們明確最精準(zhǔn)目標(biāo),這種情況下我們不需要事件冒泡。另外通過(guò)對(duì)事件冒泡的理解,我們知道程序?qū)⒆龆噍^多額外的事情,這必然增大程序開(kāi)銷。還有一個(gè)重要的問(wèn)題是:事件冒泡處理可能會(huì)激活我們本來(lái)不想激活的事件,導(dǎo)致程序錯(cuò)亂,甚至無(wú)從下手調(diào)試,這常成為對(duì)事件冒泡不熟悉程序員的棘手問(wèn)題。所以必要時(shí),我們要阻止事件冒泡。
          【不想激活的事件被激活例子】
          <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">
          //本例你實(shí)際希望點(diǎn)擊灰色盒子打開(kāi)google首頁(yè),而點(diǎn)擊黑色盒子打開(kāi)baidu首頁(yè),但結(jié)果你點(diǎn)擊灰色盒子的時(shí)候,卻是同時(shí)打開(kāi)了兩個(gè)網(wǎng)頁(yè)。其實(shí)在實(shí)際設(shè)計(jì)中較少遇到此問(wèn)題,你可能會(huì)想如果我在頁(yè)面不同DOM深處安置了不同的按鈕或鏈接,深層處的事件觸發(fā)會(huì)不會(huì)波及頂層的按鈕呢?不會(huì),因?yàn)榘粹o不能形成嵌套關(guān)系。
          function openWin(url)
          {
              window.open(url);
          }
          </script>
          下面是本人在網(wǎng)上抄的一個(gè)方法,把這個(gè)方法放在精準(zhǔn)目標(biāo)對(duì)象處理程序結(jié)尾,本事件觸發(fā)處理結(jié)束后,事件將不在進(jìn)行冒泡處理。
          【阻止事件冒泡例子】
          <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">
          //阻止事件冒泡后,你點(diǎn)擊灰色盒子,整個(gè)過(guò)程只彈一次對(duì)話框了(注意與默認(rèn)情況對(duì)比)
          function showMsg(obj,e)
          {
              alert(obj.id);
              stopBubble(e)
          }
          //阻止事件冒泡函數(shù)
          function stopBubble(e)
          {
              if (e && e.stopPropagation)
                  e.stopPropagation()
              else
                  window.event.cancelBubble=true
          }
          </script>
          posted @ 2013-10-08 12:50 Eric_jiang 閱讀(224) | 評(píng)論 (0)編輯 收藏

          1.查詢Oracle所有系統(tǒng)權(quán)限 
           
          select * from system_privilege_map   
          2.查詢Oracle所有對(duì)象權(quán)限 
           
          select * from table_privilege_map   
          3.將'授予系統(tǒng)權(quán)限'這個(gè)權(quán)限給某用戶--當(dāng)然一般采用 dba 給其他用戶授予“其他權(quán)限”,這個(gè)權(quán)限一般不需要給別人 
           
          grant any privilege to TestUser 【with admin option】//表示 TestUser 用戶有權(quán)利 給其他用戶授予 系統(tǒng)權(quán)限 。后面 表示對(duì)這個(gè)權(quán)限的維護(hù)(能否再授予其他用戶)   
          4.舉例: 授予系統(tǒng)權(quán)限 create session (連接數(shù)據(jù)庫(kù)的關(guān)鍵權(quán)限,connect角色中有這個(gè)權(quán)限,oracle角色 文章中有介紹) 
           
          1.grant create session to TestUser //TestUser就可以連接數(shù)據(jù)庫(kù)了  
          2.grant create session to TestUser with option admin //TestUser就可以連接數(shù)據(jù)庫(kù)了,并且 可以 將這個(gè)權(quán)限 給其他用戶  
          5.收回 系統(tǒng)權(quán)限 不會(huì)級(jí)聯(lián)回收 
           
          revoke create session from TestUser  
          6.關(guān)于 系統(tǒng)權(quán)限 的維護(hù) 
           
          with admin option //表示繼承后可以 授予其他用戶  
          7.關(guān)于 對(duì)象權(quán)限 的維護(hù) 
           
          with grant option //表示繼承后可以 授予其他用戶  
          8.舉例: 授予對(duì)象權(quán)限 update,select,insert,delete,all [4種等于 all] 
           
          grant select on scott.emp to TestUser 【with grant option】 //表示給TestUser 授予scott.emp的查詢權(quán)限  
          grant all on scott.emp to TestUser //表示給TestUser 授予scott.emp的select,update,insert,delete 權(quán)限  
          9.舉例: 授予 某幾列 對(duì)象權(quán)限 
           
          grant update on scott.emp(sal) to luob //指定修改某列  
          grant select on emp(ename,sal) to luob //只能查詢這指定字段  
          10.舉例:授予 alter 權(quán)限 
           
          grant alter on scott.emp to luob //授予這個(gè)表結(jié)構(gòu)的修改權(quán)限  
          11.舉例:授予 execute 權(quán)限 (用于用戶執(zhí)行其他方案的包、過(guò)程,函數(shù)) 
           
          grant execute on dbms_transaction to luob; --執(zhí)行 dbms_transaction 包的權(quán)限  
          12.舉例:授予 index 權(quán)限 
           
          grant index on scott.emp to luob 【with grant option】 //授予創(chuàng)建索引的權(quán)限  
          13.收回 對(duì)象權(quán)限 【cascade】會(huì)級(jí)聯(lián)回收 
           
          revoke select on scott.emp from TestUser【cascade】//撤銷查詢權(quán)限或者級(jí)聯(lián)撤銷  
          14.舉例:級(jí)聯(lián)回收的 
           
          grant select on emp to luobing with grant option; //授予權(quán)限 并維護(hù)  
          conn luobin/m123@ORACLE; //登錄后 給 xiaoming 權(quán)限  
          grant select on emp to xiaoming;  
          conn scott/tiger@ORACLE //scott 撤銷 luobing的權(quán)限  
          revoke select on emp from luobing cascade  
          conn xiaoming/m123@ORACLE;  
          select * from scott.emp; //表和視圖不存在  
          15.查詢當(dāng)前用戶具有的系統(tǒng)權(quán)限 
           
          select * from dba_sys_privs where grantee='SYSTEM'  
          16.查詢當(dāng)前用戶具有的對(duì)象權(quán)限 
           
          select * from dba_tab_privs where grantee='SYSTEM';  
          17.查詢當(dāng)前用戶具有的列權(quán)限 
           
          select * from dba_col_privs where grantee='SYSTEM';  
          18.查詢用戶 SCOTT 所擁有的系統(tǒng)權(quán)限 
           
          select * from dba_sys_privs where grantee in (select granted_role from dba_role_privs where grantee='SCOTT');  
          19.數(shù)據(jù)庫(kù)管理員 DBA的一些職責(zé) 
           
          1.安裝和升級(jí) oracle 數(shù)據(jù)庫(kù)  
          2.建庫(kù)建表建空間 視圖,索引。。。。  
          3.指定和并實(shí)施 備份和恢復(fù)計(jì)劃  
          4.數(shù)據(jù)庫(kù)權(quán)限管理,調(diào)優(yōu),故障排除  
          5.對(duì)高級(jí)的dba,要求能參加項(xiàng)目開(kāi)發(fā),會(huì)編寫sql語(yǔ)句 ,存儲(chǔ)過(guò)程,觸發(fā)器,規(guī)則,約束,包  
          6.管理員 還有管理初始化參數(shù)  
               show  parameter; 有 200多參數(shù) 有參數(shù)可以配置的  
          7.管理數(shù)據(jù)庫(kù)的用戶主要是 sys (董事長(zhǎng))> 和system  (總經(jīng)理)  
          20.sys,sysdba,sysoper的區(qū)別 
           
          sys:擁有oracle的基表和視圖,擁有 dba 數(shù)據(jù)庫(kù)管理  
          sysdba:系統(tǒng)管理員  
          sysoper:系統(tǒng)操作員  的角色和權(quán)限  
          system:主要存儲(chǔ)次一級(jí)的數(shù)據(jù) 如:oracle的特性和工具的管理信息和   
          dba,sysdba 角色權(quán)限 區(qū)別     
          1.存儲(chǔ)的數(shù)據(jù)重要性不一樣 ,權(quán)限不一樣   
          2.sys 必須 利用 as sysdba 或者 as sysoper 不能用normal(標(biāo)準(zhǔn))方式登錄  
          3.system 默認(rèn)登錄角色是  dba   (conn system/manager)  
          4.如果用  conn system/manager as sysdba  登錄結(jié)果和 sys 登錄一樣  
          21. sysdba 和 sysoper的權(quán)限區(qū)別 
          權(quán)限sysdbasysoper
          能夠 Startup/Shutdown 啟動(dòng)/關(guān)閉數(shù)據(jù)庫(kù)yy
          alter database open/mount/backup(設(shè)置數(shù)據(jù)庫(kù)不同的狀態(tài))yy
          改變字符集yn
          采用 create/drop database(創(chuàng)建/刪除數(shù)據(jù)庫(kù))yn
          create spfileyy
          alter database archivelog(歸檔日志)yy
          alter database recover(完全和部分恢復(fù)數(shù)據(jù)庫(kù))y只能完全恢復(fù),不能執(zhí)行部分恢復(fù)
          擁有 restricted session(會(huì)話限制)權(quán)限yy
          可以讓用戶作為sys 用戶連接yy
          登錄之后syspublic
          posted @ 2013-10-08 11:51 Eric_jiang 閱讀(253) | 評(píng)論 (0)編輯 收藏

          我們將從創(chuàng)建Oracle用戶權(quán)限表開(kāi)始談起,然后講解登陸等一般性動(dòng)作,使大家對(duì)Oracle用戶權(quán)限表有個(gè)深入的了解。

            一、創(chuàng)建

            sys;//系統(tǒng)管理員,擁有最高權(quán)限

            system;//本地管理員,次高權(quán)限

            scott;//普通用戶,密碼默認(rèn)為tiger,默認(rèn)未解鎖

            sys;//系統(tǒng)管理員,擁有最高權(quán)限

            system;//本地管理員,次高權(quán)限

            scott;//普通用戶,密碼默認(rèn)為tiger,默認(rèn)未解鎖

            二、登陸

            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;//在管理員帳戶下,創(chuàng)建用戶zhangsan

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

            create user zhangsan;//在管理員帳戶下,創(chuàng)建用戶zhangsan

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

            四,授予權(quán)限

            1、默認(rèn)的普通用戶scott默認(rèn)未解鎖,不能進(jìn)行那個(gè)使用,新建的用戶也沒(méi)有任何權(quán)限,必須授予權(quán)限

            /*管理員授權(quán)*/

            grant create session to zhangsan;//授予zhangsan用戶創(chuàng)建session的權(quán)限,即登陸權(quán)限

            grant unlimited session to zhangsan;//授予zhangsan用戶使用表空間的權(quán)限

            grant create table to zhangsan;//授予創(chuàng)建表的權(quán)限

            grante drop table to zhangsan;//授予刪除表的權(quán)限

            grant insert table to zhangsan;//插入表的權(quán)限

            grant update table to zhangsan;//修改表的權(quán)限

            grant all to public;//這條比較重要,授予所有權(quán)限(all)給所有用戶(public)

            /*管理員授權(quán)*/

            grant create session to zhangsan;//授予zhangsan用戶創(chuàng)建session的權(quán)限,即登陸權(quán)限

            grant unlimited session to zhangsan;//授予zhangsan用戶使用表空間的權(quán)限

            grant create table to zhangsan;//授予創(chuàng)建表的權(quán)限

            grante drop table to zhangsan;//授予刪除表的權(quán)限

            grant insert table to zhangsan;//插入表的權(quán)限

            grant update table to zhangsan;//修改表的權(quán)限

            grant all to public;//這條比較重要,授予所有權(quán)限(all)給所有用戶(public)

            2、oralce對(duì)權(quán)限管理比較嚴(yán)謹(jǐn),普通用戶之間也是默認(rèn)不能互相訪問(wèn)的,需要互相授權(quán)

            /*oralce對(duì)權(quán)限管理比較嚴(yán)謹(jǐn),普通用戶之間也是默認(rèn)不能互相訪問(wèn)的*/

            grant select on tablename to zhangsan;//授予zhangsan用戶查看指定表的權(quán)限

            grant drop on tablename to zhangsan;//授予刪除表的權(quán)限

            grant insert on tablename to zhangsan;//授予插入的權(quán)限

            grant update on tablename to zhangsan;//授予修改表的權(quán)限

            grant insert(id) on tablename to zhangsan;

            grant update(id) on tablename to zhangsan;//授予對(duì)指定表特定字段的插入和修改權(quán)限,注意,只能是insert和update

            grant alert all table to zhangsan;//授予zhangsan用戶alert任意表的權(quán)限

            /*oralce對(duì)權(quán)限管理比較嚴(yán)謹(jǐn),普通用戶之間也是默認(rèn)不能互相訪問(wèn)的*/

            grant select on tablename to zhangsan;//授予zhangsan用戶查看指定表的權(quán)限

            grant drop on tablename to zhangsan;//授予刪除表的權(quán)限

            grant insert on tablename to zhangsan;//授予插入的權(quán)限

            grant update on tablename to zhangsan;//授予修改表的權(quán)限

            grant insert(id) on tablename to zhangsan;

            grant update(id) on tablename to zhangsan;//授予對(duì)指定表特定字段的插入和修改權(quán)限,注意,只能是insert和update

            grant alert all table to zhangsan;//授予zhangsan用戶alert任意表的權(quán)限

            五、撤銷權(quán)限

            基本語(yǔ)法同grant,關(guān)鍵字為revoke

            基本語(yǔ)法同grant,關(guān)鍵字為revoke

            六、查看權(quán)限

            select * from user_sys_privs;//查看當(dāng)前用戶所有權(quán)限

            select * from user_tab_privs;//查看所用用戶對(duì)表的權(quán)限

            select * from user_sys_privs;//查看當(dāng)前用戶所有權(quán)限

            select * from user_tab_privs;//查看所用用戶對(duì)表的權(quán)限

            七、操作表的用戶的表

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

            select * from zhangsan.tablename

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

            select * from zhangsan.tablename

            八、權(quán)限傳遞

            即用戶A將權(quán)限授予B,B可以將操作的權(quán)限再授予C,命令如下:

            grant alert table on tablename to zhangsan with admin option;//關(guān)鍵字 with admin option

            grant alert table on tablename to zhangsan with grant option;//關(guān)鍵字 with grant option效果和admin類似

            grant alert table on tablename to zhangsan with admin option;//關(guān)鍵字 with admin option

            grant alert table on tablename to zhangsan with grant option;//關(guān)鍵字 with grant option效果和admin類似

            九、角色

            角色即權(quán)限的集合,可以把一個(gè)角色授予給用戶

            create role myrole;//創(chuàng)建角色

            grant create session to myrole;//將創(chuàng)建session的權(quán)限授予myrole

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

            drop role myrole;刪除角色

            /*但是有些權(quán)限是不能授予給角色的,比如unlimited tablespace和any關(guān)鍵字*/

            Oracle用戶權(quán)限表就介紹到這里。

          posted @ 2013-10-08 11:44 Eric_jiang 閱讀(209) | 評(píng)論 (0)編輯 收藏

          JavaScript中的String是只讀的,所以每次對(duì)String變量的操作都會(huì)在內(nèi)存中產(chǎn)生一個(gè)零時(shí)變量,如果要對(duì)字符串進(jìn)行大量的重復(fù)操作,性能和效率都會(huì)很低下,因此常用數(shù)組的方法操作字符串,即先把字符串都存儲(chǔ)在數(shù)組中,然后使用join()方法連接字符串。
          當(dāng)然可以把這種方法再演變一下,在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的方法進(jìn)行對(duì)比,會(huì)發(fā)現(xiàn)效率提高了很多。(注意:要在IE里面進(jìn)行比較,在firefox里的效率是差不多的)
          posted @ 2013-10-08 09:50 Eric_jiang 閱讀(367) | 評(píng)論 (0)編輯 收藏

          僅列出標(biāo)題
          共57頁(yè): First 上一頁(yè) 15 16 17 18 19 20 21 22 23 下一頁(yè) Last 
          主站蜘蛛池模板: 台山市| 青铜峡市| 淮安市| 武宣县| 吉林省| 宽城| 德庆县| 江永县| 新田县| 旌德县| 武陟县| 色达县| 工布江达县| 乾安县| 泰州市| 安远县| 临高县| 鹤峰县| 五华县| 十堰市| 开江县| 上栗县| 蚌埠市| 环江| 潞西市| 邵阳市| 含山县| 景谷| 易门县| 鹤峰县| 台中县| 龙泉市| 巴青县| 南汇区| 泸水县| 苏尼特右旗| 龙江县| 中牟县| 开阳县| 灵寿县| 利辛县|