posts - 262,  comments - 221,  trackbacks - 0
          link_to是Rails中提供的一個內置方法,用于產生一個超鏈接,常用的方法通常是link_to "鏈接文字", options = {}, html_options = {}, 如果我們不指定提交的方法,默認情況下將產生一個HTTP GET請求,但是我們也可以通過指定提交方法來避免某些敏感數據的泄漏。

          在《Agile web development with Rails》一書中,有這樣一個練習題:為購物網站上面的圖片添加一個超鏈接,當點擊該圖片時請求名為store的controller下add_to_cart action,同時要求使用POST方式來請求。代碼如下所示:

          <%= link_to image_tag(product.image_url),  options = {:action => "add_to_cart"},  html_options={:method => "post"%> 

          其中第一個參數image_tag是一個內置方法,用于產生一個<img src="xxx" />的HTML標簽,而options接受一個hash容器,在這個容器中只有一個參數action,它告訴了請求對應的action,于是rails會在構建<a>表情的href屬性時將其轉換為:http:localhost:3000/store/add_to_cart 這種形式:即請求StoreController下的add_to_cart方法。最重要的一定是html_options參數,它也接受一個hash容器,通過method="post"來告訴瀏覽器,采用post方式來提交請求。

          但是我們知道post通常是在form中才用到的,這里并沒有form的定義,那么是如何采用post方式來進行提交的呢?通過閱讀瀏覽器解析后的源代碼,我們可以發現rails在編譯期間做了很巧妙的處理:它創建了一個動態的、隱藏的表單來提交:

          <href="/store/add_to_cart" onclick="..."><img alt="Auto" src="/images/auto.jpg?1265130093" /></a> 

          下面就是onClick的內容:

          {
            
          //創建一個隱式的表單對象,并設置提交方式為POST,已經設置提交的URL
            var f = document.createElement('form');  
            f.style.display 
          = 'none'; 
            
          this.parentNode.appendChild(f); 
            f.method = 'POST';
           
            f.action = this.href;


            
          //為表單添加一個隱藏域,指定提交的方式參數
            var m = document.createElement('input'); 
            m.setAttribute('type', 'hidden'); 
            m.setAttribute('name', '_method'); 
            m.setAttribute('value', 'post');
            f.appendChild(m);
            
            
          //為表單添加一個隱藏域,指定當前的Session token key,防止重復提交
            var s = document.createElement('input'); 
            s.setAttribute('type', 'hidden'); 
            s.setAttribute('name', 'authenticity_token'); 
            s.setAttribute('value', '6c02dccc61c8e299bf1765bd0414355e9d8a4815'); 
            f.appendChild(s);
            
            
          //動態提交表單
            f.submit();
            
            
          return false;"
          }

          這就是采用post方式提交請求的“秘密”,rails的實現相當優雅!可是如果我們把上面的link_to代碼稍微改一下,如下面所示,會有什么結果呢?

          <%= link_to image_tag(product.image_url),  {:action => "add_to_cart", :method => "post"%> 

          我們來看看最終產生的頁面源代碼

          <href="/store/add_to_cart?method=post"><img alt="Auto" src="/images/auto.jpg?1265130093" /></a>

          很明顯,method=post變成了URL的請求參數,而不是HTTP 請求報頭了。也就是說這里產生的是一個HTTP GET請求:http://localhost:3000/store/add_to_cart?method=post,而正確的請求應該是:http://localhost:3000/store/add_to_cart

          所以我們一定要記住:options={}是用來傳遞請求參數的,而html_options={}是用來設置請求報頭的,不能搞混!


          -------------------------------------------------------------
          生活就像打牌,不是要抓一手好牌,而是要盡力打好一手爛牌。
          posted on 2010-05-17 16:41 Paul Lin 閱讀(6507) 評論(4)  編輯  收藏 所屬分類: RoR


          FeedBack:
          # re: Rails中的link_to方法注意點[未登錄]
          2011-04-18 16:40 | test
          測試哈  回復  更多評論
            
          # re: Rails中的link_to方法注意點[未登錄]
          2011-04-18 16:41 | test
          test  回復  更多評論
            
          # re: Rails中的link_to方法注意點[未登錄]
          2011-04-18 16:42 | test
          ajax comment  回復  更多評論
            
          # re: Rails中的link_to方法注意點[未登錄]
          2013-08-30 15:41 | 陌生人
          我以為你要講什么呢? 就是不要搞混呀   回復  更多評論
            
          <2010年5月>
          2526272829301
          2345678
          9101112131415
          16171819202122
          23242526272829
          303112345

          常用鏈接

          留言簿(21)

          隨筆分類

          隨筆檔案

          BlogJava熱點博客

          好友博客

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 新丰县| 铁岭市| 博爱县| 长治县| 叶城县| 房产| 金溪县| 大兴区| 旬阳县| 定安县| 济阳县| 夹江县| 即墨市| 寿光市| 安塞县| 佛山市| 禹州市| 祁东县| 蓝田县| 新乡县| 鄢陵县| 新安县| 乐清市| 绥芬河市| 德阳市| 莲花县| 滁州市| 二手房| 青铜峡市| 谢通门县| 来安县| 托克逊县| 玉门市| 洛南县| 南昌县| 和林格尔县| 聊城市| 芮城县| 苏尼特左旗| 涞水县| 方正县|