京山游俠

          專注技術(shù),拒絕扯淡
          posts - 50, comments - 868, trackbacks - 0, articles - 0
            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          說到AJAX,每個人都不會陌生,畢竟這兩年它太流行了。然而,真正哪些地方需要AJAX,并不是每個人都能夠把握得很好。使用AJAX可以開發(fā)豪華的基于瀏覽器的富客戶端界面,然而其開發(fā)量的龐大和調(diào)試的艱難,讓每一個程序員如同生活在地獄中一般。

          我認(rèn)為,真正需要AJAX的不外乎兩種情況:

          1、用戶不希望他關(guān)注的信息離開他的視線的時候。比如填寫某些表單的時候,有時候辛辛苦苦填寫的東西,一點(diǎn)提交按鈕,全沒了,如果某個字段驗(yàn)證失敗,則所有的東西都要從頭再填,著實(shí)讓人郁悶。雖然設(shè)計較好的網(wǎng)站可以保留用戶填寫的信息,但是在提交后頁面刷新的一瞬間,用戶仍然有一種不安感。
          2、用戶不希望一點(diǎn)小的更新就刷新整個龐大的頁面的時候。比如用戶回復(fù)一篇很長且充滿圖片的文章,雖然回復(fù)的內(nèi)容只有幾個字,但是卻要等待頁面漫長的刷新,也會造成不好的用戶體驗(yàn)。

          如果單單只是為了實(shí)現(xiàn)絢麗的效果而使用AJAX,我個人認(rèn)為不可取。

          根據(jù)以上的總結(jié),我這里想實(shí)現(xiàn)這樣一個注冊用戶的功能,讓用戶在提交信息的時候不需要刷新頁面,所有的字段驗(yàn)證全部發(fā)回服務(wù)器端進(jìn)行,驗(yàn)證的錯誤信息再顯示到表單頁面,整個過程不刷新頁面,知道注冊成功后跳轉(zhuǎn)到首頁,如下圖:

          1、供用戶填寫的表單
          41.JPG

          2、用戶填寫信息后,表單變?yōu)椴豢删庉嫞⑻崾緮?shù)據(jù)正在提交
          42.JPG

          3、如果驗(yàn)證失敗,顯示錯誤信息,同時表單變?yōu)榭捎米層脩粜薷?br />43.JPG

          4、注冊成功后,提示注冊成功,然后跳轉(zhuǎn)到首頁
          44.JPG

          看似簡單的功能,我卻足足花了兩天時間才搞定,所以形容為在地獄里漫步。下面,大家會看到我的設(shè)計思路和遇到的各種問題。

          要做AJAX開發(fā),首先當(dāng)然少不了挑選一個AJAX框架。我最喜歡的是Prototype,因?yàn)槲矣憛拸?fù)雜的功能。在SpringSide中集成有Prototype,我們只需要在jsp文件中加入如下代碼,就可以使用了:

          < script? src ="scripts/prototype.js" ></ script >


          事實(shí)上,我只使用了Prototype的一個函數(shù),它就是Ajax.Request(),它簡化了我們繁瑣的實(shí)例化XHR、監(jiān)控請求狀態(tài)的過程,語法如下:

          var ?ajax? = ? new ?Ajax.Request(url,? {method:? " get " ?,?onComplete:onResponse} ?);


          method為方法類型,如get,post等;onComplete為回調(diào)函數(shù),通常在這個函數(shù)中完成對相應(yīng)數(shù)據(jù)的解析和顯示。

          看似水落石出,只要在用戶點(diǎn)擊注冊按鈕的時候調(diào)用這個函數(shù)就可以做到異步提交數(shù)據(jù)了。

          問題一、如何將表單中的數(shù)據(jù)發(fā)回服務(wù)器?

          我們都知道,當(dāng)我們提交整個網(wǎng)頁的時候,其表單中的數(shù)據(jù)也一并POST過去了,基本上無需我們操心;而AJAX不然,AJAX向服務(wù)器提交請求的時候,除了url,其它屁信息都沒有。沒有辦法,我們只有自己取出表單中的數(shù)據(jù),把它添加到url參數(shù)中,然后傳遞給服務(wù)器。因此,當(dāng)提交按鈕被點(diǎn)擊時,我的處理函數(shù)是這樣的:

          function ?onSubmit() {

          ????
          var ?url? = ? " RegUser.do?method=submit " ;
          ????
          // 將表單數(shù)據(jù)添加到url中以便于使用GET傳遞到服務(wù)器
          ???? var ?inputs? = ?userForm.all.tags( " input " );
          ????
          for ( var ?i = 0 ;?i? < ?inputs.length;?i ++ ) {
          ????????url?
          = ?url? + ? " & " ? + ?inputs[i].name? + ? " = " ? + ?inputs[i].value;
          ????????
          // 設(shè)置表單為不可用狀態(tài)
          ????????inputs[i].disabled? = ? " true " ;
          ????}

          ????
          // 提示用戶正在提交數(shù)據(jù)
          ????$( " doing " ).style.pixelTop? = ?document.body.scrollTop? + ? 230 ;
          ????$(
          " doing " ).style.left? = ? 250 ;
          ????$(
          " doing " ).style.display = " block " ;
          ????
          ????
          // 使用AJAX將數(shù)據(jù)傳遞到服務(wù)器,并接受服務(wù)器的回應(yīng)
          ???? var ?ajax? = ? new ?Ajax.Request(url,? {method:? " get " ?,?onComplete:onResponse} ?);
          }
          ?



          乍一看來,解決這個問題似乎并不復(fù)雜,但不知大家想過沒有,如果用戶輸入非法字符怎么處理。在url中,有幾個字符是會被引起錯誤的,比如"@"和"#","@"會讓服務(wù)器只把"@"后面的字符串當(dāng)成有效url地址,"#"代表一個網(wǎng)頁中的錨點(diǎn)。也有可能還有更多的非法字符,我們暫時還沒有發(fā)現(xiàn)。我曾經(jīng)想過使用JavaScript的escape()來將表單中的字符編碼,但是又會引起中文無法傳遞到服務(wù)器。唉,看來除非在客戶端使用JavaScript代碼來過濾掉這些字符,是在也想不出其它的辦法。

          問題二、服務(wù)器返回什么數(shù)據(jù)給AJAX對象?

          我們通過AJAX把數(shù)據(jù)異步傳遞到服務(wù)器,等服務(wù)器驗(yàn)證完畢后,服務(wù)器給我們回復(fù)什么格式的數(shù)據(jù)呢?是XML?普通文本?JSON?還是其它。XML我首先排除,因?yàn)榻馕鏊墓ぷ髁刻罅恕.?dāng)前,JSON最是流行。但是我更加懶惰,我直接返回有效的JavaScript代碼,這樣,我在AJAX的onComplete時,只需要一行代碼,如下:

          function ??onResponse(request)?? {
          ????eval(request.responseText);
          }


          問題三、AJAX讓Validator框架走開?

          在Struts中,有一個驗(yàn)證框架Validator,它可以很方便的完成對ActionForm的驗(yàn)證。但是一旦我們使用AJAX,Validator就派不上任何用場,因?yàn)橹挥性趈sp文件中使用Struts的<html:form>系列標(biāo)簽,才能讓Struts表我們的表單數(shù)據(jù)自動封裝到ActionForm中,但是前文已經(jīng)提過,我們的表單數(shù)據(jù)是通過url參數(shù)傳遞的,所以除非自己擴(kuò)展Struts,否則我們跟Validator無緣。

          于是,所有的驗(yàn)證代碼我們必須得在服務(wù)器端自己編寫,即要考慮周全,又要防止出錯。幸好SpringSide提供的HibernateEntityDao<T>讓我們在驗(yàn)證用戶名和昵稱是否重復(fù)時省了一大把勁。我的服務(wù)器端代碼如下:
          //?????????獲取用戶提交的數(shù)據(jù)并驗(yàn)證?????
          ????public?ActionForward?submit(ActionMapping?mapping,?ActionForm?form,
          ????????????HttpServletRequest?request,?HttpServletResponse?response)
          ????????????
          throws?Exception?{
          ????????
          boolean?success?=?true;
          ????????String?result?
          =?"";
          ????????User?user?
          =?new?User();

          ????????
          //?驗(yàn)證用戶名????????
          ????????String?name?=?new?String(request.getParameter("name").getBytes(
          ????????????????
          "ISO-8859-1"),?"GB2312");
          ????????user.setName(name);
          ????????
          if?(name?==?null?||?name.equals(""))?{
          ????????????success?
          =?false;
          ????????????result?
          +=?"name_err.innerHTML='用戶名不能為空';";
          ????????}
          ?else?if?(!name.matches("^[A-Za-z0-9_]*$"))?{
          ????????????success?
          =?false;
          ????????????result?
          +=?"name_err.innerHTML='用戶名只能包含字母、數(shù)字和下劃線';";
          ????????}
          ?else?if?(name.length()?>?20)?{
          ????????????success?
          =?false;
          ????????????result?
          +=?"name_err.innerHTML='用戶名不能超過20個字符';";
          ????????}

          ????????
          //?判斷用戶名是否重復(fù)
          ????????else?if?(userManager.isNotUnique(user,?"name"))?{
          ????????????success?
          =?false;
          ????????????result?
          +=?"name_err.innerHTML='該用戶名已經(jīng)被注冊';";
          ????????}
          else{
          ????????????result?
          +=?"name_err.innerHTML='';";
          ????????}


          ????????
          //?驗(yàn)證昵稱
          ????????String?monicker?=?new?String(request.getParameter("monicker").getBytes(
          ????????????????
          "ISO-8859-1"),?"GB2312");
          ????????user.setMonicker(monicker);
          ????????
          if?(monicker?==?null?||?monicker.equals(""))?{
          ????????????success?
          =?false;
          ????????????result?
          +=?"monicker_err.innerHTML='昵稱不能為空';";
          ????????}
          ?else?if?(monicker.matches("^.*[~!@#$%^&*()-=+<>?/'\";:]+.*$"))?{
          ????????????success?=?false;
          ????????????result?
          +=?"monicker_err.innerHTML='昵稱不能包含特殊字符';";
          ????????}
          ?else?if?(monicker.length()?>?15)?{
          ????????????success?
          =?false;
          ????????????result?
          +=?"monicker_err.innerHTML='昵稱不能超過15個字符';";
          ????????}
          //?判斷昵稱是否重復(fù)
          ????????else?if?(userManager.isNotUnique(user,?"monicker"))?{
          ????????????success?
          =?false;
          ????????????result?
          +=?"monicker_err.innerHTML='該用昵稱已經(jīng)被使用';";
          ????????}
          else{
          ????????????result?
          +=?"monicker_err.innerHTML='';";
          ????????}


          ????????
          //?驗(yàn)證兩次輸入的密碼是否匹配
          ????????String?password?=?new?String(request.getParameter("password").getBytes(
          ????????????????
          "ISO-8859-1"),?"GB2312");
          ????????user.setPassword(password);
          ????????String?password_again?
          =?new?String(request.getParameter(
          ????????????????
          "password_again").getBytes("ISO-8859-1"),?"GB2312");
          ????????
          if?(password?==?null?||?password.equals(""))?{
          ????????????success?
          =?false;
          ????????????result?
          +=?"password_err.innerHTML='密碼不能為空';";
          ????????}
          ?else?if?(password_again?==?null?||?password_again.equals(""))?{
          ????????????success?
          =?false;
          ????????????result?
          +=?"password_err.innerHTML='確認(rèn)密碼不能為空';";
          ????????}
          ?else?if?(!password.equals(password_again))?{
          ????????????success?
          =?false;
          ????????????result?
          +=?"password_err.innerHTML='兩次輸入的密碼不匹配';";
          ????????}
          else{
          ????????????result?
          +=?"password_err.innerHTML='';";
          ????????}


          ????????
          //?驗(yàn)證密碼問題和問題答案,規(guī)則和昵稱相同
          ????????String?question?=?new?String(request.getParameter("question").getBytes(
          ????????????????
          "ISO-8859-1"),?"GB2312");
          ????????user.setQuestion(question);
          ????????
          if?(question?==?null?||?question.equals(""))?{
          ????????????success?
          =?false;
          ????????????result?
          +=?"question_err.innerHTML='問題不能為空';";
          ????????}
          ?else?if?(question.matches("^.*[~!@#$%^&*()-=+<>?/'\";:]+.*$"))?{
          ????????????success?=?false;
          ????????????result?
          +=?"question_err.innerHTML='問題不能包含特殊字符';";
          ????????}?
          else?if?(question.length()?>?15)?{
          ????????????success?
          =?false;
          ????????????result?
          +=?"question_err.innerHTML='問題不能超過15個字符';";
          ????????}
          else{
          ????????????result?
          +=?"question_err.innerHTML='';";
          ????????}


          ????????String?answer?
          =?new?String(request.getParameter("answer").getBytes(
          ????????????????
          "ISO-8859-1"),?"GB2312");
          ????????user.setQuestion(question);
          ????????
          if?(answer?==?null?||?answer.equals(""))?{
          ????????????success?
          =?false;
          ????????????result?
          +=?"answer_err.innerHTML='答案不能為空';";
          ????????}
          ?else?if?(answer.matches("^.*[~!@#$%^&*()-=+<>?/'\";:]+.*$"))?{
          ????????????success?=?false;
          ????????????result?
          +=?"answer_err.innerHTML='答案不能包含特殊字符';";
          ????????}?
          else?if?(answer.length()?>?15)?{
          ????????????success?
          =?false;
          ????????????result?
          +=?"answer_err.innerHTML='答案不能超過15個字符';";
          ????????}
          else{
          ????????????result?
          +=?"answer_err.innerHTML='';";
          ????????}


          ????????
          //?驗(yàn)證email
          ????????String?email?=?new?String(request.getParameter("email").getBytes(
          ????????????????
          "ISO-8859-1"),?"GB2312");
          ????????user.setEmail(email);
          ????????
          if?(email?==?null?||?email.equals(""))?{
          ????????????success?
          =?false;
          ????????????result?
          +=?"email_err.innerHTML='Email不能為空';";
          ????????}
          ?else?if?(!email.matches("^[a-zA-Z0-9]*@[a-zA-Z0-9]*$"))?{
          ????????????success?
          =?false;
          ????????????result?
          +=?"email_err.innerHTML='不是有效的電子郵箱';";
          ????????}
          ?else?if?(email.length()?>?40)?{
          ????????????success?
          =?false;
          ????????????result?
          +=?"email_err.innerHTML='Email不能超過40個字符';";
          ????????}
          else{
          ????????????result?
          +=?"email_err.innerHTML='';";
          ????????}


          ????????
          //?驗(yàn)證QQ號碼
          ????????String?qq?=?new?String(request.getParameter("qq")
          ????????????????.getBytes(
          "ISO-8859-1"),?"GB2312");
          ????????user.setQq(qq);
          ????????
          if?(qq?==?null?||?qq.equals(""))?{
          ????????????success?
          =?false;
          ????????????result?
          +=?"qq_err.innerHTML='QQ號碼不能為空';";
          ????????}
          ?else?if?(!qq.matches("^\\d*$"))?{
          ????????????success?
          =?false;
          ????????????result?
          +=?"qq_err.innerHTML='不是有效的QQ號碼';";
          ????????}
          ?else?if?(qq.length()?>?12)?{
          ????????????success?
          =?false;
          ????????????result?
          +=?"qq_err.innerHTML='QQ號碼不能超過12位';";
          ????????}
          ?else?if?(qq.length()?<?5)?{
          ????????????result?
          +=?"qq_err.innerHTML='QQ號碼不能少于5位';";
          ????????}
          else{
          ????????????result?
          +=?"qq_err.innerHTML='';";
          ????????}


          ????????
          //?驗(yàn)證驗(yàn)證碼
          ????????String?validateImage?=?new?String(request.getParameter("validateImage")
          ????????????????.getBytes(
          "ISO-8859-1"),?"GB2312");
          ????????
          if?(validateImage?==?null
          ????????????????
          ||?validateImage.equals("")
          ????????????????
          ||?!validateImage.equals(request.getSession().getAttribute(
          ????????????????????????
          "validateString")))?{
          ????????????success?
          =?false;
          ????????????result?
          +=?"validateImage_err.innerHTML='驗(yàn)證碼輸入錯誤。如看不清,點(diǎn)擊圖片更換';";
          ????????}
          else{
          ????????????result?
          +=?"validateImage_err.innerHTML='';";
          ????????}

          ????????
          ????????
          //如果驗(yàn)證不成功,則調(diào)用JavaScript的failed()函數(shù),否則,調(diào)用sucess();
          ????????if(success?==?false){
          ????????????result?
          +=?"failed();";
          ????????????response.setCharacterEncoding(
          "GB2312");
          ????????????response.getOutputStream().println(result);
          ????????????response.flushBuffer();
          ????????}
          else{
          ????????????
          //如果驗(yàn)證成功,把數(shù)據(jù)寫入數(shù)據(jù)庫中,要防止重復(fù)提交
          ????????????if(this.isTokenValid(request)){
          ????????????????userManager.save(user);
          ????????????????
          this.resetToken(request);
          ????????????}

          ????????????response.setCharacterEncoding(
          "GB2312");
          ????????????response.getOutputStream().println(
          "success();");
          ????????????response.flushBuffer();
          ????????}

          ????????
          return?null;
          ????}

          客戶端的failed()和success()函數(shù)如下:
          function?failed(){
          ????
          //掩藏提示信息
          ????$("doing").style.display="none";
          ????
          //設(shè)置表單為可用狀態(tài)
          ????var?inputs?=?userForm.all.tags("input");
          ????
          for(var?i=0;?i?<?inputs.length;?i++){
          ????????inputs[i].disabled?
          =?"";
          ????}

          }


          function?success(){
          ????$(
          "doing").style.display="block";
          ????$(
          "doing").style.color="#0000FF";
          ????$(
          "doing").innerHTML?=?"用戶注冊成功,將跳轉(zhuǎn)到首頁!";
          ????
          //4秒鐘跳到首頁
          ????setTimeout("location.href='welcome.do';",4000);
          }


          問題四、中文亂碼問題如何解決?

          我想每個人在使用AJAX的時候肯定都遇到過中文亂碼的問題,我也不例外,這個問題困擾我的時間也不短,后來我總算時把它搞清楚了:AJAX使用的是另外一個線程,所以它的字符編碼是和頁面無關(guān)的,也就是說,它總是用GB2312編碼向服務(wù)器發(fā)送數(shù)據(jù),并且總是把接受到的數(shù)據(jù)當(dāng)GB2312來理解,這是由我們操作系統(tǒng)決定的,我們大陸的操作系統(tǒng)默認(rèn)編碼都應(yīng)該是GB2312吧。因此,在接受數(shù)據(jù)的時候,我們少不了:
          String?name?=?new?String(request.getParameter("name").getBytes(
          ????????????????
          "ISO-8859-1"),?"GB2312");

          而發(fā)送數(shù)據(jù)的時候,也少不了:
          response.setCharacterEncoding("GB2312");
          ????????????response.getOutputStream().println(result);
          ????????????response.flushBuffer();


          除此之外,還有瀏覽器之間對象不兼容的問題,可見寫一個AJAX應(yīng)用到處都是陷阱。

          從上面大家可以看出,對于用戶注冊,我全部使用的/RegUser.do來進(jìn)行處理,它繼承自SpringSide的StrutsAction,是DispatherAction的子類。它的配置如下:
          struts-config.xml的action-mappings節(jié)中:
          <action?path="/RegUser"?scope="request"?parameter="method">
          ????????????????
          <forward?name="agree"?path="/RegUser_Agree.jsp"/>
          ????????????????
          <forward?name="apply"?path="/RegUser_Apply.jsp"/>
          ????????????
          </action>

          action-servlet.xml:
          <?xml?version="1.0"?encoding="UTF-8"?>
          <!DOCTYPE?beans?PUBLIC?"-//SPRING//DTD?BEAN?2.0//EN"?"http://www.springframework.org/dtd/spring-beans-2.0.dtd">
          <beans?default-autowire="byName"?default-lazy-init="true">
          ????
          <!--?按模塊導(dǎo)入Spring?Action?Config-->
          ????
          <import?resource="modules/spring-config-admin.xml"/>

          ????
          <!--?簡單應(yīng)用直接在此定義Action
          ????????<bean?name="/user"?class="org.springside.helloworld.web.UserAction"/>
          ????????
          -->
          ????
          <bean?name="/welcome"?class="com.xkland.action.WelcomeAction"/>
          ????
          <bean?name="/RegUser"?class="com.xkland.action.RegUserAction"/>
          </beans>

          而這個com.xkland.action.RegUserAction的完整代碼如下,希望大家多提意見:
          package?com.xkland.action;

          import?javax.servlet.http.HttpServletRequest;
          import?javax.servlet.http.HttpServletResponse;

          import?org.apache.struts.action.ActionForm;
          import?org.apache.struts.action.ActionMapping;
          import?org.apache.struts.action.ActionForward;
          import?org.springside.core.web.StrutsAction;

          import?com.xkland.manager.UserManager;
          import?com.xkland.util.ImageUtil;
          import?java.awt.image.BufferedImage;
          import?javax.imageio.ImageIO;
          import?com.xkland.domain.User;

          public?class?RegUserAction?extends?StrutsAction?{
          ????
          private?ImageUtil?imageUtil;

          ????
          private?UserManager?userManager;

          ????
          public?void?setUserManager(UserManager?userManager)?{
          ????????
          this.userManager?=?userManager;
          ????}


          ????
          public?void?setImageUtil(ImageUtil?imageUtil)?{
          ????????
          this.imageUtil?=?imageUtil;
          ????}


          ????
          //?重定向到會員注冊協(xié)議頁面??
          ????public?ActionForward?agree(ActionMapping?mapping,?ActionForm?form,
          ????????????HttpServletRequest?request,?HttpServletResponse?response)?
          {
          ????????
          return?mapping.findForward("agree");
          ????}


          ????
          //?重定向到填寫表單頁面??
          ????public?ActionForward?apply(ActionMapping?mapping,?ActionForm?form,
          ????????????HttpServletRequest?request,?HttpServletResponse?response)?
          {
          ????????
          //?使用Token防止重復(fù)提交
          ????????saveToken(request);
          ????????
          return?mapping.findForward("apply");
          ????}


          ????
          //?構(gòu)造驗(yàn)證圖片??????
          ????public?ActionForward?createValidateImage(ActionMapping?mapping,
          ????????????ActionForm?form,?HttpServletRequest?request,
          ????????????HttpServletResponse?response)?
          {
          ????????BufferedImage?image?
          =?imageUtil.createValidateImage(request
          ????????????????.getSession());
          ????????response.setContentType(
          "image/jpeg");
          ????????
          try?{
          ????????????ImageIO.write(image,?
          "jpeg",?response.getOutputStream());
          ????????????response.flushBuffer();
          ????????}
          ?catch?(Exception?e)?{

          ????????}


          ????????
          return?null;
          ????}


          ????
          //獲取用戶提交的數(shù)據(jù)并驗(yàn)證
          ????public?ActionForward?submit(ActionMapping?mapping,?ActionForm?form,
          ????????????HttpServletRequest?request,?HttpServletResponse?response)
          ????????????
          throws?Exception?{
          //上面已貼代碼,此處省略
          ????????????}

          }

          評論

          # re: SpringSide開發(fā)實(shí)戰(zhàn)(六):AJAX,在地獄中漫步  回復(fù)  更多評論   

          2007-03-02 08:12 by dragonsz1
          居然是沙發(fā),

          一早上班就看到沫沫的好文,實(shí)在太高興了

          果然關(guān)注沫沫的BLOG沒錯~~~

          支持,幫助很大啊~~~

          # re: SpringSide開發(fā)實(shí)戰(zhàn)(六):AJAX,在地獄中漫步  回復(fù)  更多評論   

          2007-03-02 09:28 by 壞男孩
          這篇比較全面標(biāo)記一下

          # re: SpringSide開發(fā)實(shí)戰(zhàn)(六):AJAX,在地獄中漫步  回復(fù)  更多評論   

          2007-03-02 10:00 by anonymity
          贊成這個
          "如果單單只是為了實(shí)現(xiàn)絢麗的效果而使用AJAX,我個人認(rèn)為不可取。"
          這樣在action中校驗(yàn)數(shù)據(jù)不敢恭維,那怕是demo。

          # re: SpringSide開發(fā)實(shí)戰(zhàn)(六):AJAX,在地獄中漫步  回復(fù)  更多評論   

          2007-03-02 11:14 by chinajj
          "我曾經(jīng)想過使用JavaScript的escape()來將表單中的字符編碼,但是又會引起中文無法傳遞到服務(wù)器。唉,看來除非在客戶端使用JavaScript代碼來過濾掉這些字符,是在也想不出其它的辦法。"
          -----------------
          可以在服務(wù)器端用java代碼模擬javascript的unescape()函數(shù)(網(wǎng)上有類似的例子)來接受使用JavaScript的escape()加密過的字符串。這樣不會有中文問題了吧。

          # re: SpringSide開發(fā)實(shí)戰(zhàn)(六):AJAX,在地獄中漫步[未登錄]  回復(fù)  更多評論   

          2007-03-02 12:22 by thinkbase.net
          我們都知道,當(dāng)我們提交整個網(wǎng)頁的時候,其表單中的數(shù)據(jù)也一并POST過去了,基本上無需我們操心;而AJAX不然,AJAX向服務(wù)器提交請求的時候,除了url,其它屁信息都沒有
          -----------------------
          這里有誤導(dǎo)之嫌, AJAX也是一樣可以 POST 的啊

          # re: SpringSide開發(fā)實(shí)戰(zhàn)(六):AJAX,在地獄中漫步  回復(fù)  更多評論   

          2007-03-02 12:39 by boolean
          提兩點(diǎn):
          var url = " RegUser.do?method=submit " ;
          // 將表單數(shù)據(jù)添加到url中以便于使用GET傳遞到服務(wù)器
          var inputs = userForm.all.tags( " input " );
          for ( var i = 0 ; i < inputs.length; i ++ ) {
          url = url + " & " + inputs[i].name + " = " + inputs[i].value;
          // 設(shè)置表單為不可用狀態(tài)
          inputs[i].disabled = " true " ;
          }
          可以用prototype的Form對象的兩個方法做
          Form.disable
          Form.serialize

          # re: SpringSide開發(fā)實(shí)戰(zhàn)(六):AJAX,在地獄中漫步  回復(fù)  更多評論   

          2007-03-03 10:57 by 海邊沫沫
          @boolean
          謝謝提示,看來得好好研究Prototype才行啊,因?yàn)樗拇_可以簡化很多我們的工作。

          # re: SpringSide開發(fā)實(shí)戰(zhàn)(六):AJAX,在地獄中漫步  回復(fù)  更多評論   

          2007-03-03 10:58 by 海邊沫沫
          @thinkbase.net
          AJAX可以POST,但是提交的內(nèi)容依然不包含表單數(shù)據(jù)

          # re: SpringSide開發(fā)實(shí)戰(zhàn)(六):AJAX,在地獄中漫步  回復(fù)  更多評論   

          2007-03-03 11:05 by 海邊沫沫
          @anonymity
          不錯,應(yīng)該進(jìn)行重構(gòu),把所有的驗(yàn)證代碼提取出來,另外組成一個Util類

          # re: SpringSide開發(fā)實(shí)戰(zhàn)(六):AJAX,在地獄中漫步  回復(fù)  更多評論   

          2007-03-08 13:11 by penny
          ajax 可以提交 xml 數(shù)據(jù)流,樓主想在url 后面加提交的參數(shù)據(jù)的做法有些不解。

          # re: SpringSide開發(fā)實(shí)戰(zhàn)(六):AJAX,在地獄中漫步  回復(fù)  更多評論   

          2007-03-09 22:56 by billbai
          var url = " RegUser.do?method=submit " ;
          var myAjax = new Ajax.Request(url,{method: 'get', parameters: Form.serialize(signinForm), onComplete: showResponse,onFailure: reportError});

          通過這種方式可以獲得表單所有對象;

          # re: SpringSide開發(fā)實(shí)戰(zhàn)(六):AJAX,在地獄中漫步  回復(fù)  更多評論   

          2007-03-11 18:12 by 京山游俠
          @billbai
          謝謝

          # re: SpringSide開發(fā)實(shí)戰(zhàn)(六):AJAX,在地獄中漫步  回復(fù)  更多評論   

          2007-07-30 16:22 by 小白之家
          還是請momo給貼出代碼

          # re: SpringSide開發(fā)實(shí)戰(zhàn)(六):AJAX,在地獄中漫步  回復(fù)  更多評論   

          2007-12-12 10:31 by yxw
          強(qiáng)悍!衷心希望您把完整的代碼發(fā)上了!我很想學(xué)習(xí)啊!

          # re: SpringSide開發(fā)實(shí)戰(zhàn)(六):AJAX,在地獄中漫步  回復(fù)  更多評論   

          2008-08-06 16:44 by ONE
          實(shí)際上prototype是可以將FORM表單中的元素序列化的
          主站蜘蛛池模板: 惠州市| 贵南县| 静安区| 南和县| 林甸县| 临漳县| 临武县| 含山县| 保山市| 金堂县| 宁国市| 政和县| 林芝县| 岳西县| 天门市| 柯坪县| 东港市| 新兴县| 麦盖提县| 双城市| 抚远县| 长春市| 崇仁县| 徐闻县| 平阴县| 江城| 和硕县| 新乡县| 广德县| 中西区| 华亭县| 德格县| 岳阳市| 砀山县| 玉门市| 克什克腾旗| 马关县| 泗水县| 清水县| 馆陶县| 项城市|