<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # 表單,FormData 對象 ## 表單概述 表單(`<form>`)用來收集用戶提交的數據,發送到服務器。比如,用戶提交用戶名和密碼,讓服務器驗證,就要通過表單。表單提供多種控件,讓開發者使用,具體的控件種類和用法請參考 HTML 語言的教程。本章主要介紹 JavaScript 與表單的交互。 ```html <form action="/handling-page" method="post"> <div> <label for="name">用戶名:</label> <input type="text" id="name" name="user_name" /> </div> <div> <label for="passwd">密碼:</label> <input type="password" id="passwd" name="user_passwd" /> </div> <div> <input type="submit" id="submit" name="submit_button" value="提交" /> </div> </form> ``` 上面代碼就是一個簡單的表單,包含三個控件:用戶名輸入框、密碼輸入框和提交按鈕。 用戶點擊“提交”按鈕,每一個控件都會生成一個鍵值對,鍵名是控件的`name`屬性,鍵值是控件的`value`屬性,鍵名和鍵值之間由等號連接。比如,用戶名輸入框的`name`屬性是`user_name`,`value`屬性是用戶輸入的值,假定是“張三”,提交到服務器的時候,就會生成一個鍵值對`user_name=張三`。 所有的鍵值對都會提交到服務器。但是,提交的數據格式跟`<form>`元素的`method`屬性有關。該屬性指定了提交數據的 HTTP 方法。如果是 GET 方法,所有鍵值對會以 URL 的查詢字符串形式,提交到服務器,比如`/handling-page?user_name=張三&user_passwd=123&submit_button=提交`。下面就是 GET 請求的 HTTP 頭信息。 ```http GET /handling-page?user_name=張三&user_passwd=123&submit_button=提交 Host: example.com ``` 如果是 POST 方法,所有鍵值對會連接成一行,作為 HTTP 請求的數據體發送到服務器,比如`user_name=張三&user_passwd=123&submit_button=提交`。下面就是 POST 請求的頭信息。 ```http POST /handling-page HTTP/1.1 Host: example.com Content-Type: application/x-www-form-urlencoded Content-Length: 74 user_name=張三&user_passwd=123&submit_button=提交 ``` 注意,實際提交的時候,只要鍵值不是 URL 的合法字符(比如漢字“張三”和“提交”),瀏覽器會自動對其進行編碼。 點擊`submit`控件,就可以提交表單。 ```html <form> <input type="submit" value="提交"> </form> ``` 上面表單就包含一個`submit`控件,點擊這個控件,瀏覽器就會把表單數據向服務器提交。 注意,表單里面的`<button>`元素如果沒有用`type`屬性指定類型,那么默認就是`submit`控件。 ```html <form> <button>提交</button> </form> ``` 上面表單的`<button>`元素,點擊以后也會提交表單。 除了點擊`submit`控件提交表單,還可以用表單元素的`submit()`方法,通過腳本提交表單。 ```javascript formElement.submit(); ``` 表單元素的`reset()`方法可以重置所有控件的值(重置為默認值)。 ```javascript formElement.reset() ``` ## FormData 對象 ### 概述 表單數據以鍵值對的形式向服務器發送,這個過程是瀏覽器自動完成的。但是有時候,我們希望通過腳本完成這個過程,構造或編輯表單的鍵值對,然后通過腳本發送給服務器。瀏覽器原生提供了 FormData 對象來完成這項工作。 `FormData()`首先是一個構造函數,用來生成表單的實例。 ```javascript var formdata = new FormData(form); ``` `FormData()`構造函數的參數是一個 DOM 的表單元素,構造函數會自動處理表單的鍵值對。這個參數是可選的,如果省略該參數,就表示一個空的表單。 下面是一個表單。 ```html <form id="myForm" name="myForm"> <div> <label for="username">用戶名:</label> <input type="text" id="username" name="username"> </div> <div> <label for="useracc">賬號:</label> <input type="text" id="useracc" name="useracc"> </div> <div> <label for="userfile">上傳文件:</label> <input type="file" id="userfile" name="userfile"> </div> <input type="submit" value="Submit!"> </form> ``` 我們用`FormData()`處理上面這個表單。 ```javascript var myForm = document.getElementById('myForm'); var formData = new FormData(myForm); // 獲取某個控件的值 formData.get('username') // "" // 設置某個控件的值 formData.set('username', '張三'); formData.get('username') // "張三" ``` ### 實例方法 FormData 提供以下實例方法。 - `FormData.get(key)`:獲取指定鍵名對應的鍵值,參數為鍵名。如果有多個同名的鍵值對,則返回第一個鍵值對的鍵值。 - `FormData.getAll(key)`:返回一個數組,表示指定鍵名對應的所有鍵值。如果有多個同名的鍵值對,數組會包含所有的鍵值。 - `FormData.set(key, value)`:設置指定鍵名的鍵值,參數為鍵名。如果鍵名不存在,會添加這個鍵值對,否則會更新指定鍵名的鍵值。如果第二個參數是文件,還可以使用第三個參數,表示文件名。 - `FormData.delete(key)`:刪除一個鍵值對,參數為鍵名。 - `FormData.append(key, value)`:添加一個鍵值對。如果鍵名重復,則會生成兩個相同鍵名的鍵值對。如果第二個參數是文件,還可以使用第三個參數,表示文件名。 - `FormData.has(key)`:返回一個布爾值,表示是否具有該鍵名的鍵值對。 - `FormData.keys()`:返回一個遍歷器對象,用于`for...of`循環遍歷所有的鍵名。 - `FormData.values()`:返回一個遍歷器對象,用于`for...of`循環遍歷所有的鍵值。 - `FormData.entries()`:返回一個遍歷器對象,用于`for...of`循環遍歷所有的鍵值對。如果直接用`for...of`循環遍歷 FormData 實例,默認就會調用這個方法。 下面是`get()`、`getAll()`、`set()`、`append()`方法的例子。 ```javascript var formData = new FormData(); formData.set('username', '張三'); formData.append('username', '李四'); formData.get('username') // "張三" formData.getAll('username') // ["張三", "李四"] formData.append('userpic[]', myFileInput.files[0], 'user1.jpg'); formData.append('userpic[]', myFileInput.files[1], 'user2.jpg'); ``` 下面是遍歷器的例子。 ```javascript var formData = new FormData(); formData.append('key1', 'value1'); formData.append('key2', 'value2'); for (var key of formData.keys()) { console.log(key); } // "key1" // "key2" for (var value of formData.values()) { console.log(value); } // "value1" // "value2" for (var pair of formData.entries()) { console.log(pair[0] + ': ' + pair[1]); } // key1: value1 // key2: value2 // 等同于遍歷 formData.entries() for (var pair of formData) { console.log(pair[0] + ': ' + pair[1]); } // key1: value1 // key2: value2 ``` ## 表單的內置驗證 ### 自動校驗 表單提交的時候,瀏覽器允許開發者指定一些條件,它會自動驗證各個表單控件的值是否符合條件。 ```html <!-- 必填 --> <input required> <!-- 必須符合正則表達式 --> <input pattern="banana|cherry"> <!-- 字符串長度必須為6個字符 --> <input minlength="6" maxlength="6"> <!-- 數值必須在1到10之間 --> <input type="number" min="1" max="10"> <!-- 必須填入 Email 地址 --> <input type="email"> <!-- 必須填入 URL --> <input type="URL"> ``` 如果一個控件通過驗證,它就會匹配`:valid`的 CSS 偽類,瀏覽器會繼續進行表單提交的流程。如果沒有通過驗證,該控件就會匹配`:invalid`的 CSS 偽類,瀏覽器會終止表單提交,并顯示一個錯誤信息。 ```css input:invalid { border-color: red; } input, input:valid { border-color: #ccc; } ``` ### checkValidity() 除了提交表單的時候,瀏覽器自動校驗表單,還可以手動觸發表單的校驗。表單元素和表單控件都有`checkValidity()`方法,用于手動觸發校驗。 ```javascript // 觸發整個表單的校驗 form.checkValidity() // 觸發單個表單控件的校驗 formControl.checkValidity() ``` `checkValidity()`方法返回一個布爾值,`true`表示通過校驗,`false`表示沒有通過校驗。因此,提交表單可以封裝為下面的函數。 ```javascript function submitForm(action) { var form = document.getElementById('form'); form.action = action; if (form.checkValidity()) { form.submit(); } } ``` ### willValidate 屬性 控件元素的`willValidate`屬性是一個布爾值,表示該控件是否會在提交時進行校驗。 ```javascript // HTML 代碼如下 // <form novalidate> // <input id="name" name="name" required /> // </form> var input = document.querySelector('#name'); input.willValidate // true ``` ### validationMessage 屬性 控件元素的`validationMessage`屬性返回一個字符串,表示控件不滿足校驗條件時,瀏覽器顯示的提示文本。以下兩種情況,該屬性返回空字符串。 - 該控件不會在提交時自動校驗 - 該控件滿足校驗條件 ```javascript // HTML 代碼如下 // <form><input type="text" required></form> document.querySelector('form input').validationMessage // "請填寫此字段。" ``` 下面是另一個例子。 ```javascript var myInput = document.getElementById('myinput'); if (!myInput.checkValidity()) { document.getElementById('prompt').innerHTML = myInput.validationMessage; } ``` ### setCustomValidity() 控件元素的`setCustomValidity()`方法用來定制校驗失敗時的報錯信息。它接受一個字符串作為參數,該字符串就是定制的報錯信息。如果參數為空字符串,則上次設置的報錯信息被清除。 這個方法可以替換瀏覽器內置的表單驗證報錯信息,參數就是要顯示的報錯信息。 ```html <form action="somefile.php"> <input type="text" name="username" placeholder="Username" pattern="[a-z]{1,15}" id="username" > <input type="submit"> </form> ``` 上面的表單輸入框,要求只能輸入小寫字母,且不得超過15個字符。如果輸入不符合要求(比如輸入“ABC”),提交表單的時候,Chrome 瀏覽器會彈出報錯信息“Please match the requested format.”,禁止表單提交。下面使用`setCustomValidity()`方法替換掉報錯信息。 ```javascript var input = document.getElementById('username'); input.oninvalid = function (event) { event.target.setCustomValidity( '用戶名必須是小寫字母,不能為空,最長不超過15個字符' ); } ``` 上面代碼中,`setCustomValidity()`方法是在`invalid`事件的監聽函數里面調用。該方法也可以直接調用,這時如果參數不為空字符串,瀏覽器就會認為該控件沒有通過校驗,就會立刻顯示該方法設置的報錯信息。 ```javascript /* HTML 代碼如下 <form> <p><input type="file" id="fs"></p> <p><input type="submit"></p> </form> */ document.getElementById('fs').onchange = checkFileSize; function checkFileSize() { var fs = document.getElementById('fs'); var files = fs.files; if (files.length > 0) { if (files[0].size > 75 * 1024) { fs.setCustomValidity('文件不能大于 75KB'); return; } } fs.setCustomValidity(''); } ``` 上面代碼一旦發現文件大于 75KB,就會設置校驗失敗,同時給出自定義的報錯信息。然后,點擊提交按鈕時,就會顯示報錯信息。這種校驗失敗是不會自動消除的,所以如果所有文件都符合條件,要將報錯信息設為空字符串,手動消除校驗失敗的狀態。 ### validity 屬性 控件元素的屬性`validity`屬性返回一個`ValidityState`對象,包含當前校驗狀態的信息。 該對象有以下屬性,全部為只讀屬性。 - `ValidityState.badInput`:布爾值,表示瀏覽器是否不能將用戶的輸入轉換成正確的類型,比如用戶在數值框里面輸入字符串。 - `ValidityState.customError`:布爾值,表示是否已經調用`setCustomValidity()`方法,將校驗信息設置為一個非空字符串。 - `ValidityState.patternMismatch`:布爾值,表示用戶輸入的值是否不滿足模式的要求。 - `ValidityState.rangeOverflow`:布爾值,表示用戶輸入的值是否大于最大范圍。 - `ValidityState.rangeUnderflow`:布爾值,表示用戶輸入的值是否小于最小范圍。 - `ValidityState.stepMismatch`:布爾值,表示用戶輸入的值不符合步長的設置(即不能被步長值整除)。 - `ValidityState.tooLong`:布爾值,表示用戶輸入的字數超出了最長字數。 - `ValidityState.tooShort`:布爾值,表示用戶輸入的字符少于最短字數。 - `ValidityState.typeMismatch`:布爾值,表示用戶填入的值不符合類型要求(主要是類型為 Email 或 URL 的情況)。 - `ValidityState.valid`:布爾值,表示用戶是否滿足所有校驗條件。 - `ValidityState.valueMissing`:布爾值,表示用戶沒有填入必填的值。 下面是一個例子。 ```javascript var input = document.getElementById('myinput'); if (input.validity.valid) { console.log('通過校驗'); } else { console.log('校驗失敗'); } ``` 下面是另外一個例子。 ```javascript var txt = ''; if (document.getElementById('myInput').validity.rangeOverflow) { txt = '數值超過上限'; } document.getElementById('prompt').innerHTML = txt; ``` 如果想禁止瀏覽器彈出表單驗證的報錯信息,可以監聽`invalid`事件。 ```javascript var input = document.getElementById('username'); var form = document.getElementById('form'); var elem = document.createElement('div'); elem.id = 'notify'; elem.style.display = 'none'; form.appendChild(elem); input.addEventListener('invalid', function (event) { event.preventDefault(); if (!event.target.validity.valid) { elem.textContent = '用戶名必須是小寫字母'; elem.className = 'error'; elem.style.display = 'block'; input.className = 'invalid animated shake'; } }); input.addEventListener('input', function(event){ if ( 'block' === elem.style.display ) { input.className = ''; elem.style.display = 'none'; } }); ``` 上面代碼中,一旦發生`invalid`事件(表單驗證失敗),`event.preventDefault()`用來禁止瀏覽器彈出默認的驗證失敗提示,然后設置定制的報錯提示框。 ### 表單的 novalidate 屬性 表單元素的 HTML 屬性`novalidate`,可以關閉瀏覽器的自動校驗。 ```html <form novalidate> </form> ``` 這個屬性也可以在腳本里設置。 ```javascript form.noValidate = true; ``` 如果表單元素沒有設置`novalidate`屬性,那么提交按鈕(`<button>`或`<input>`元素)的`formnovalidate`屬性也有同樣的作用。 ```html <form> <input type="submit" value="submit" formnovalidate> </form> ``` ## enctype 屬性 表單能夠用四種編碼,向服務器發送數據。編碼格式由表單的`enctype`屬性決定。 假定表單有兩個字段,分別是`foo`和`baz`,其中`foo`字段的值等于`bar`,`baz`字段的值是一個分為兩行的字符串。 ``` The first line. The second line. ``` 下面四種格式,都可以將這個表單發送到服務器。 **(1)GET 方法** 如果表單使用`GET`方法發送數據,`enctype`屬性無效。 ```html <form action="register.php" method="get" onsubmit="AJAXSubmit(this); return false;" > </form> ``` 數據將以 URL 的查詢字符串發出。 ```http ?foo=bar&baz=The%20first%20line.%0AThe%20second%20line. ``` **(2)application/x-www-form-urlencoded** 如果表單用`POST`方法發送數據,并省略`enctype`屬性,那么數據以`application/x-www-form-urlencoded`格式發送(因為這是默認值)。 ```html <form action="register.php" method="post" onsubmit="AJAXSubmit(this); return false;" > </form> ``` 發送的 HTTP 請求如下。 ```http Content-Type: application/x-www-form-urlencoded foo=bar&baz=The+first+line.%0D%0AThe+second+line.%0D%0A ``` 上面代碼中,數據體里面的`%0D%0A`代表換行符(`\r\n`)。 **(3)text/plain** 如果表單使用`POST`方法發送數據,`enctype`屬性為`text/plain`,那么數據將以純文本格式發送。 ```html <form action="register.php" method="post" enctype="text/plain" onsubmit="AJAXSubmit(this); return false;" > </form> ``` 發送的 HTTP 請求如下。 ```http Content-Type: text/plain foo=bar baz=The first line. The second line. ``` **(4)multipart/form-data** 如果表單使用`POST`方法,`enctype`屬性為`multipart/form-data`,那么數據將以混合的格式發送。 ```html <form action="register.php" method="post" enctype="multipart/form-data" onsubmit="AJAXSubmit(this); return false;" > </form> ``` 發送的 HTTP 請求如下。 ```http Content-Type: multipart/form-data; boundary=---------------------------314911788813839 -----------------------------314911788813839 Content-Disposition: form-data; name="foo" bar -----------------------------314911788813839 Content-Disposition: form-data; name="baz" The first line. The second line. -----------------------------314911788813839-- ``` 這種格式也是文件上傳的格式。 ## 文件上傳 用戶上傳文件,也是通過表單。具體來說,就是通過文件輸入框選擇本地文件,提交表單的時候,瀏覽器就會把這個文件發送到服務器。 ```html <input type="file" id="file" name="myFile"> ``` 此外,還需要將表單`<form>`元素的`method`屬性設為`POST`,`enctype`屬性設為`multipart/form-data`。其中,`enctype`屬性決定了 HTTP 頭信息的`Content-Type`字段的值,默認情況下這個字段的值是`application/x-www-form-urlencoded`,但是文件上傳的時候要改成`multipart/form-data`。 ```html <form method="post" enctype="multipart/form-data"> <div> <label for="file">選擇一個文件</label> <input type="file" id="file" name="myFile" multiple> </div> <div> <input type="submit" id="submit" name="submit_button" value="上傳" /> </div> </form> ``` 上面的 HTML 代碼中,file 控件的`multiple`屬性,指定可以一次選擇多個文件;如果沒有這個屬性,則一次只能選擇一個文件。 ```javascript var fileSelect = document.getElementById('file'); var files = fileSelect.files; ``` 然后,新建一個 FormData 實例對象,模擬發送到服務器的表單數據,把選中的文件添加到這個對象上面。 ```javascript var formData = new FormData(); for (var i = 0; i < files.length; i++) { var file = files[i]; // 只上傳圖片文件 if (!file.type.match('image.*')) { continue; } formData.append('photos[]', file, file.name); } ``` 最后,使用 Ajax 向服務器上傳文件。 ```javascript var xhr = new XMLHttpRequest(); xhr.open('POST', 'handler.php', true); xhr.onload = function () { if (xhr.status !== 200) { console.log('An error occurred!'); } }; xhr.send(formData); ``` 除了發送 FormData 實例,也可以直接 AJAX 發送文件。 ```javascript var file = document.getElementById('test-input').files[0]; var xhr = new XMLHttpRequest(); xhr.open('POST', 'myserver/uploads'); xhr.setRequestHeader('Content-Type', file.type); xhr.send(file); ``` ## 參考鏈接 - [HTML5 Form Validation With the “pattern” Attribute](https://webdesign.tutsplus.com/tutorials/html5-form-validation-with-the-pattern-attribute--cms-25145), Thoriq Firdaus
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看