html_03 | HTML——③ HTML 表單詳解

本文推薦 PC 端閱讀~

本文版權歸 「公衆號 | 前端一萬小時」 全部,未經受權,請勿轉載!
複製代碼

獲取編號.png

html_03
複製代碼

涉及面試題.png

1. post 和 get 方式提交數據有什麼區別?
2. 在 input 裏,name 有什麼做用?
3. label 有什麼做用?如何使用?
4. radio 如何分組?
5. placeholder 屬性有什麼做用?
6. type=hidden 隱藏域有什麼做用?舉例說明。
7. CSRF 攻擊是什麼?如何防範?
8. 網頁驗證碼是幹嗎的?是爲了解決什麼安全問題?
9. 常見 web 安全及防禦原理?
10. 如下哪一種寫法會致使 checkbox 被勾選:
  ✅ <input type="checkbox" checked=false ><input type="checkbox" checked=true ><input type="checkbox" checked="" ><input type="checkbox" checked><input type="checkbox" >

11. 若是想勾選 checkbox,如下哪些是推薦的寫法:
  ❌ <input type="checkbox" checked=true ><input type="checkbox" checked="true" ><input type="checkbox" checked="checked"><input type="checkbox" checked>

12. 有 4 個 radio,想 id1 和 id2 一組,id3 和 id4 一組,實現單選,如下說法正確的是?(不定項)
    <input id="id1" type="radio"> 
    <input id="id2" type="radio"> 
    <input id="id3" type="radio"> 
    <input id="id4" type="radio"> 
  ✅ id1 和 id2 須要設置相同的 name,id3 和 id4 須要設置相同的 name。
  ❌ id1 和 id2 須要設置相同的 value,id3 和 id4 須要設置相同的 value。
  ❌ id1 和 id2 須要設置相同的 class,id3 和 id4 須要設置相同的 class。
  ❌ id1 和 id2 須要設置相同的 label,id3 和 id4 須要設置相同的 label。

13. 關於 post 和 get 的區別,如下說法正確的是?
  ✅ get 的語義是「要」數據,post 的語義是「給」數據或者「建立」數據。
  ✅ get 把參數拼裝成 url,發 get 請求其實是瀏覽器請求拼接後的 url。
  ❌ get提交的數據沒有最大長度限制,post 提交的數據有最大長度限制(和服務端的設置有關)。
  ✅ get 提交的數據有最大長度限制,根本緣由是瀏覽器地址欄對輸入的 url 有最大長度限制,超過會截斷。
  ✅ post 相對更「安全」一些,由於 get 請求拼裝的 url 會保存在瀏覽器歷史記錄,到了服務器以後通常也有保存的請求日誌能夠直接看到請求參數。
  ✅ 從嚴格的安全意義上講,只要是 http 的請求,都不安全。https + post 才安全。
複製代碼

前言: 這一篇咱們集中精力攻克一個知識點——表單,這個知識點在工做中用處很普遍,不論是網頁仍是 APP,只要涉及到「註冊」,就會有他的身影,屬於必掌握項。css



1 「表單」的相關定義

  • HTML 表單是一個能夠用來輸入用戶信息的一個單子,它是一個包含「表單元素」的區域。
  • 「表單元素」是指:容許用戶在表單中(好比:文本域、下拉列表、複選框等等)輸入信息的元素。
  • 對於服務商(網頁、APP 等運營者)來講,這個單子能夠用來收集不一樣類型的用戶輸入。

2 「表單」的實際運用及相關元素註釋

  • 任務:寫出如下圖片的 HTML

03-01.png

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>HTML表單</title>
    <style type="text/css">       #txa {         width: 300px;         height: 200px;         margin-left: -12px;           }     </style>
</head>
<body>
<div class="login">
   <input type="text" name="sex">             <!--註釋1-->
   <form action="/getinfo" method="get">      <!--註釋2-->
       <div class="username">                 <!--註釋3-->
          <label for="username">姓名</label>   <!--註釋4-->

          <input id="username"  type="text" name="username" value="Oliver"> 
          <!--註釋5-->

       </div>
       <div class="password">
          <label for="password" >密碼</label>

          <input id="password" type="password" name="password" placeholder="輸入密碼">
          <!--註釋6-->

       </div>
       <div class="sex">
          <label>性別</label>                                   <!--註釋7-->
          <input type="radio" name="sex" value="男" checked>男  <!--註釋8--> 
          <input type="radio" name="sex" value="女">女
       </div>
       <div class="orientation">
         <label>取向</label>
         <input type="radio" name="orientation" value="男">男
         <input type="radio" name="orientation" value="女" checked>女
       </div>
      <div class="hobby">
        <label>愛好</label>
        <input type="checkbox" name="hobby" value="reading" checked>讀書  <!--註釋9-->
        <input type="checkbox" name="hobby" value="tour" checked>旅遊
        <input type="checkbox" name="hobby" value="design" checked>室內設計
      </div>
      <div>
        <label for="txa">評論:</label>
        <textarea id="txa" name="article">是個好人!                                  
        </textarea>                                            <!--註釋10-->
      </div>
      <div class="file">
        <input type="file" name="myfile" accept="image/png">   <!--註釋11-->
      </div>  
      <div class="mycar">
        <label>個人car</label>
        <select name="mycar">                                  <!--註釋12-->
          <option value="三菱" selected>三菱</option>            <!--註釋13-->
          <option value="奧迪">奧迪</option>
          <option value="MINI">MINI</option>
        </select>
        <input type="submit" value="提交">                       <!--註釋14-->
        <input type="button" value="不提交">                     <!--註釋15-->
        <input type="reset" value="重置輸入">                     <!--註釋16-->
        <input type="hidden" name="csrf" value="123456oliver">  <!--註釋17-->
      </div>
   </form>
</div>
</body>
</html>
複製代碼

註釋 1:html

<input type="text" name="sex">
複製代碼
  • HTML 表單必須用 <form>…</form> 標籤來包裹住全部 input 輸入框。當你點擊「提交」的時候,他就會把這個 <form> 所包裹的全部 input 裏邊的信息「提交」給 form 對應的後臺地址上(詳見:註釋 2)。
  • 本註釋對應的 input 沒有被 <form> 包裹,所以在「提交」的時候不會把裏邊填寫的信息「提交」給後臺。

註釋 2:前端

<form action="/getinfo" method="get">
複製代碼
  • 必須用 <form> 包裹住全部 input 輸入框;
  • action 是指「表單」提交處理對應的後臺路徑;
  • method 是指「表單」提交的方法(get 或 post):

① get
本質上是一個 URL 的拼接,即把全部參數拼接到一塊兒,造成一個新的 URL 。當咱們點「提交」這個按鈕時,瀏覽器作了什麼事情呢?web

  • 首先,他把這個 input 裏,type=text 中的東西拿出來,獲得裏邊的內容,裏邊的內容就是咱們輸入的文字、密碼等;
  • 而後,把 input 裏的 name 拿出來(username/password);
  • 最後,username=填寫的名字、password=輸入的密碼等,而後把它拼成一個 URL。(如:localhost:8080/abc?username=Oliver&password=123456

② post
URL 不會發生變化,他不像 get 那樣 URL會變成參數的拼接而後傳輸給後臺。但用戶填寫的數據依然會經過瀏覽器傳輸給後臺(相對 get 來講更加的安全),且較之 get,他的 URL 字符長度不會由於瀏覽器地址欄字符長度所限制(而 get ,若是參數不少致使字符過長,則會被瀏覽器截斷)。面試

③ 何時選 get/post ?數據庫

  • get :直譯爲「獲得」,那每每就是向後臺要數據的時候用。好比:向後臺查論文,查數據。
  • post :直譯爲「傳遞」,則每每用於向後臺傳數據。好比:寫了一大篇文章傳給後臺。

註釋 3:後端

<div class="username">
複製代碼

用一個 div 來區分出一個「塊」,用一個 class 來創建一個「類」(如下同理)。瀏覽器

註釋 4:安全

<label for="username">姓名</label>   <!--註釋4-->

<input id="username"  type="text" name="username" value="Oliver">  <!--註釋5-->
複製代碼
  • label for 是爲了給一個 input 輸入框前邊加上可點擊的說明文字;
  • label 裏邊的 forinput 裏邊的 id 連用,是爲了:正常狀況下,我要在這個輸入框裏邊輸入的話,我僅僅點擊前邊的說明文字是沒反應的,我必需要點擊這個輸入框才能進入可輸入模式。而這裏的 label forid 的連用就能夠實現點擊輸入框前邊的輸入文字也能夠進入輸入模式。(注意:有 for 就必須有一個 id)

註釋 5:bash

<label for="username">姓名</label>   <!--註釋4-->

<input id="username"  type="text" name="username" value="Oliver">  <!--註釋5-->
複製代碼
  • type="text" ,這個輸入框是用於輸入單行文本。咱們使用 <input> 元素來建立一些不一樣的控件,type 屬性肯定了這是什麼類型的控件;
  • name="username" ,絕大多數表單元素都須要一個名字,至關於用戶輸入數據的一個標識符。後臺服務器腳本將使用這個元素名,並提取裏邊的參數(見:註釋 2,表單是怎樣提交給後臺的);
  • value="Oliver" ,這裏我輸入例如一個初始值——Oliver,咱們能夠輸入或不輸入任何初始文本(例如:value="")。

註釋 6:

<div class="password">
  <label for="password" >密碼</label>

  <input id="password" type="password" name="password" placeholder="輸入密碼">
  <!--註釋6-->

</div>
複製代碼
  • type="password" ,這個輸入框是用於輸入密碼;
  • placeholder="輸入密碼" ,這個屬性用陰影文字來引導用戶在框裏「輸入密碼」。

註釋 7:

<div class="sex">
  <label>性別</label>                                   <!--註釋7-->
  <input type="radio" name="sex" value="男" checked>男  <!--註釋8--> 
  <input type="radio" name="sex" value="女"></div>
複製代碼

單純用了 label ,裏邊沒有 for ,與之對應的 input 裏邊也沒有 id 。由於這個 input 是「單選框」類型,沒有必要點擊文字(性別)就選擇或輸入。

註釋 8:

<div class="sex">
  <label>性別</label>                                   <!--註釋7-->
  <input type="radio" name="sex" value="男" checked>男  <!--註釋8--> 
  <input type="radio" name="sex" value="女"></div>
複製代碼
  • type="radio" ,這個是「單選鈕輸入」,用於單選;
  • name 都是 sex ,咱們單選提交後,後臺腳本在提取各個 name 的參數時,就會對應的 sex=男/女 ;
……value="男" checked>男
……value="女">女
複製代碼

由於是勾選,沒有在輸入框輸入東西,若是沒有 value 值,那麼用戶只勾選後提交,咱們後臺是沒有東西的。因此,必須手動添加 value 值,讓勾選後,後臺能夠顯示對應勾選的 value 值;

  • checked 是指這裏默認先勾選上。

註釋 9:

<div class="hobby">
  <label>愛好</label>
  <input type="checkbox" name="hobby" value="reading" checked>讀書  <!--註釋9-->
  <input type="checkbox" name="hobby" value="tour" checked>旅遊
  <input type="checkbox" name="hobby" value="design" checked>室內設計
</div>
複製代碼
  • type="checkbox" ,這個是「複選框」,用於多選;
  • 同理 type="radio" ,name 都是 hobby ;
  • 同理因爲都是勾選,所以手動添加 value 值。

註釋 10:

<div>
  <label for="txa">評論:</label>
  <textarea id="txa" name="article">是個好人!                                  
  </textarea>                                            <!--註釋10-->
</div>
複製代碼
  • textarea ,這個是多行文本輸入,區別於單行文本輸入 type="text"
  • 因爲 <textarea> 是一個閉合的標籤,所以初始值(是個好人)要寫在標籤裏。

註釋 11:

<div class="file">
  <input type="file" name="myfile" accept="image/png">   <!--註釋11-->
</div>  
複製代碼
  • type="file" ,這個是用於文件上傳,如上傳身份信息等;
  • accept="image/png" ,accept 屬性能夠用來約束上傳文件的格式,例如這裏只能上傳 image/png (但實際工做中,咱們前端這樣單方面的限制是不靠譜的,還須要後端也作相應的限制)。

註釋 十二、註釋 13:

<div class="mycar">
  <label>個人car</label>
  <select name="mycar">   
      <option value="三菱" selected>三菱</option> 
      <option value="奧迪">奧迪</option>
      <option value="MINI">MINI</option>
  </select>
複製代碼
  • 這個寫法就再也不是 input 了,而是 select 和 option 的結合;
  • 這個是用於「在下拉菜單中選擇」;
  • 這裏的 value 值的手動添加也同理於 type="radio"type="checkbox" 中的 value;
  • selected 能夠用來「預勾選」。

註釋 1四、1五、16:

<input type="submit" value="提交">                       <!--註釋14-->
<input type="button" value="不提交">                     <!--註釋15-->
<input type="reset" value="重置輸入">                    <!--註釋16-->
複製代碼
  • type="submit"type="reset"type="button" 都是能夠點擊的按鈕;
  • 有 value 值或沒有 value 值得區別主要在於:這個按鈕上是否有與 value 對應的相關文字。

註釋 17:

<input type="hidden" name="csrf" value="123456oliver">
複製代碼
  • 這一組代碼在頁面顯示上沒有任何效果,但點完「提交」後,這組代碼裏邊的相關參數是會提交給後臺的;

  • 這組代碼的做用:

    1. 暫存一些信息。好比在 <input type="hidden" name="_" value="_"> 裏邊埋了一個值,下次咱們要用的時候,就直接能夠定位到這個元素去獲取它的值,獲取到後就能夠用了,但用戶什麼都不知道;
    2. 因爲能夠暫存信息,那麼在使用一些安全策略時,能夠用到這個功能—— csrf 攻擊。

先複習相關文章:《老生常談的從 URL 輸入到頁面展示背後發生的事》

好比打開一個頁面,實際這個頁面是寫好的模板,而後後端往裏邊填充數據,填充好後讓你看獲得。

換句話說,這個頁面是後端處理後獲得的頁面。那假如說,後端在渲染這個頁面給咱們時(返回給瀏覽器以前),他就經過這種方式在這裏加上這個值—— <input type="hidden" name="csrf" value="123456oliver"> ,他把這個東西寫好後發給你,發給你以後,你看到的頁面表面上沒什麼特別的變化,可實際上有一個點已經埋下了—— name="csrf" value="123456oliver"

接下來,用戶該幹什麼仍是繼續幹,填寫用戶名、密碼等,填寫完後點擊「提交」。當用戶點擊「提交」按鈕的時候,用戶所填寫的全部信息都會提交給後臺,同時會提交 <input type="hidden" name="csrf" value="123456oliver"> 裏的這個值:csrf=123456oliver

提交給後臺後,後臺就能夠作個「校驗」,看看這個值對不對,若是這個值是對的,那你用戶的提交是安全的。

假如說沒有這樣一個參數、接口,那任何人均可以僞造一個這樣的頁面。好比說他知道咱們的請求地址( action 的值),就能夠用 method 發送一個 get/post 請求,把全部的參數都發進去,那就至關於修改了數據庫。

但若是咱們有這個值—— csrf=123456oliver ,而他沒有這樣一個值,或獲得的值是錯的,那他即便發送了這些數據,服務器也是不承認的。

只有當他發的這個值是對的,才能說明他有這個權限,表示他是一個合法的用戶。這樣就能夠阻止 csrf 攻擊。
固然,csrf 攻擊這個東西還涉及到 cookie 的校驗等,後續再做相關的文章講解。



後記: 知識點不少、很雜,但靜下心來,用兩個顯示器,一邊把本文代碼拷貝放到 JS Bin 裏邊運行,一邊對着本文的註釋一行行把代碼理順,最後會發現不過如此。前端的學習更多的是耐力的考驗,有興趣當然重要,但不付諸時間和耐力是不行的。

祝好,qdywxs ♥ you!

相關文章
相關標籤/搜索