Warning:
This wiki has been archived and is now read-only.
HTML5/association-of-controls-and-forms
控制項與表單的連結
一個表單連結元素可以與一個 form 元素有連結,為它的主表單。若一個表單連結元素並沒有一個相連的 form 元素,則稱其主表單為空值。
一個表單連結元素預設為與最近的祖先 form 元素(下面描述),但是 form 屬性可以覆蓋這個設定。
form 元素,這個功能提供了一個繞道方法。若網頁作者在一個表單連結元素上指定一個 form 屬性的值,則該值必須為該元素主 Document 裡的一個 form 元素的 ID。
form 元素 ,生成這種文件(比如說使用操作 DOM 的腳本)卻是可能的,這讓本小節的規則變得複雜。由於歷史因素,HTML 解析器會產生與不是其祖先的 form 元素相連的表單連結元素,更增加複雜度。當一個表單連結元素誕生時,使用者代理必須將其主表單初始化為空值(沒有主表單)。
當一個表單連結元素與一個表單相連時,使用者代理必須將其主表單設為該表單。
當一個表單連結元素的祖先鏈變動(比如說使用者將它或是它的祖先進入到該Document 或是從該 Document 離去)時,使用者代理必須重設該元素的主表單。當一個表單連結元素的 form 屬性被設置、變更、移去時,使用者代理必須重設該元素的主表單。
當一個表單連結元素有 form 屬性且該 Document 的任一個元素的 ID 更動時,使用者代理必須重設該表單連結元素的主表單。
當一個表單連結元素有 form 屬性且一個有 ID 的元素進入到該 Document 或是從該 Document 離去時,使用者代理必須重設該表單連結元素的主表單。
當使用者代理要重設一個表單連結元素的主表單時,它必須執行下列步驟:
- 若該元素的主表單不為空值,且該元素沒有
form內容屬性,且祖先鏈變動後該元素的主表單是最近的祖先form元素,則不做任何事並退出這些步驟。 - 設該元素的主表單為空值。
- 若該元素有內容屬性
form,執行以下步驟: - 否則,若該表單連結元素有一個祖先
form元素,則將該表單連結元素與最近的祖先form相連。 - 否則,該元素沒有相連表單。
...
<form id="a">
<div id="b"></div>
</form>
<script>
document.getElementById('b').innerHTML =
'<table><tr><td><form id="c"><input id="d"></table>' +
'<input id="e">';
</script>
...
"d" 的主表單是巢狀表單內測的 "c",但 "e" 的主表單是外側的 "a"。
事情發生順序如下:首先,"e" 節點在 HTML 解析器內與 "c" 相連。後來,innerHTML 演算法將這些節點從暫時文件移到 "b" 元素上。在這個時候,這些節點看到祖先鏈的變動,也因此解析器的「魔法」相連被重設成一般的祖先相連。
form 元素的規定。表單連結元素 有 IDL 屬性 form。該屬性在獲取時必須回傳元素的主表單,或是在沒有主表單時回傳空值。
表單控制項的共通屬性
為表單控制項命名
內容屬性 name 可以用來命名表單控制項,表單的命名直接影響表單提交的過程與 form 元素的 elements 物件。若網頁作者欲設定此屬性,則它的取值必不可為空字串。
本規範允許任何非空的 name 值,但是 "_charset_" 與 "isindex" 這兩個值有特殊作用:
isindex
若一個用 application/x-www-form-urlencoded 作為提交機制的表單的第一個控制項為文字控制項且其名字為這個值,則表單僅提交這個控制項取值,不送出名字。
_charset_
若沒有 value 屬性的隱藏控制項的名字為這個值,則表單提交時的控制項取值自動變成提交的編碼。
啟用和停用控制項
內容屬性 disabled 是一個布林屬性。
若一個表單控制項設有 disabled 屬性,或者它是一個設有 disabled 屬性的 fieldset 元素的子嗣但「不是」該 fieldset 元素的第一個 legend 子元素(若存在)的子嗣,則這個表單控制項處於停用狀態。
處於停用狀態的表單控制項必須防止任何使用者互動任務源上隊列的 click 事件被分發到元素上。
約束驗證:若一個元素處於停用狀態,則不進行這個元素的約束驗證。
IDL 屬性 disabled 必須反映內容屬性 disabled。
控制項的取值
每個表單控制項都具有取值與確認標記。(僅有 input 元素有後者)。這些是描述使用者與控制項互動狀態的變數。
為了定義有 multiple 屬性的 input 元素的約束驗證行為,input 元素也可能會有另外的取值組變數。
控制項的自動聚焦
內容屬性 autofocus 讓網頁作者可以選定頁面讀取完成同時該獲得焦距的控制項,這讓使用者可以立即輸入內容而不需要手動給主要控制項焦距。
網頁作者必不可指定 autofocus 屬性在超過一個文件裡的元素上。
當設置了 autofocus 屬性的元素進入到文件裡時,使用者代理應該執行下列步驟:
- 設目標為元素的
Document。 - 若目標沒有瀏覽上下文,退出這些步驟。
- 若目標的瀏覽上下文沒有頂級瀏覽上下文(例如,目標是沒有父瀏覽上下文的嵌套的瀏覽上下文),退出這些步驟。
- 若目標的瀏覽上下文在創建的時候不設有沙盒中的自動機能瀏覽上下文標記,退出這些步驟。
- 若目標的來源與目標的父瀏覽上下文中此時有焦距的元素的
Document的來源不相同,退出這些步驟。 - 若目標的來源與目標的頂級瀏覽上下文的現行文件的來源不相同,退出這些步驟。
- 若使用者代理曾經為了回應一個頂級瀏覽上下文的現行文件與目標的頂級瀏覽上下文的現行文件相同的元素進入一個
Document的事件,退出這些步驟。 - 若可以由使用者的行為(例如開始在表單控制項輸入內容)推論使用者不希望聚焦改變,可以退出這些步驟。
- 將以下任務排入隊列:確認該元素可得到焦距,若可,執行該元素的聚焦步驟。使用者代理也可以改變文件的捲軸位置,或是用其他方法讓使用者注意到該元素。此任務的任務源為 DOM 操作任務源。
IDL 屬性 autofocus 必須反映同樣名稱的內容屬性。
<input maxlength="256" name="q" value="" autofocus> <input type="submit" value="Search">
限制使用者的輸入長度
髒值標記控制的表單控制項 maxlength 屬性可以用來宣告使用者能輸入的字符數限制。
若網頁作者欲指定一個元素的表單控制項 maxlength 屬性,該屬性值必須是合法非負整數。若使用者指定此屬性且使用者代理對這個值使用非負整數解析規則進行解析可以得到一個數字,則該數字是此元素的最大容許取值長度 。若使用者未指定此屬性或解析屬性值發生錯誤,則沒有最大容許取值長度。
約束驗證:若一個元素具有最大容許取值長度,髒值標記為真,取值最後一次的更改是透過使用者(而不是腳本造成的改變),且元素取值的代碼點長度大於元素的最大容許取值長度,則該元素苦於過長。
使用者代理可以阻止使用者進行讓元素的取值的代碼點長度大於元素的最大容許取值長度的行為。
表單提交
網頁作者可以在 form 元素或是提交按鈕(提交表單按鈕的代表原素,例如 type 屬性處於提交按鈕狀態的 input 元素)上指定表單提交用屬性。
網頁作者可以指定在 form 元素上的表單提交用屬性有 action、enctype、method、novalidate 與 target。
網頁作者可以指定在提交按鈕上的表單提交用屬性有相對的 formaction、formenctype、formmethod、formnovalidate 與 formtarget。若未指定,這些屬性的預設值是 form 元素上對應屬性的值。
若網頁作者指定內容屬性 action 與 formaction,則取值必須是可能有兩邊空白的合法非空網址。
若一個元素為提交按鈕且它具有 formaction 屬性,則它的行動是該屬性的值,否則此元素的行動是其主表單 action 屬性(若有)的值,否則此元素的行動是空字串。
內容屬性 method 與 formmethod 是有以下關鍵字與狀態的列舉屬性:
- 對應到 GET 狀態的關鍵字
get,表示 HTTP GET 方法。 - 對應到 POST 狀態的關鍵字
post,表示 HTTP POST 方法。
這兩個屬性的失蹤預設值是 GET 狀態。
一個元素的方法是這兩個狀態其一。若此元素為提交按鈕且它具有 formmethod 屬性,則此元素的方法是該屬性的狀態,否則此元素的方法是其主表單 method 屬性的狀態。
內容屬性 enctype 與 enctype 是有以下關鍵字與狀態的列舉屬性:
- 關鍵字 "
application/x-www-form-urlencoded" 與對應的狀態。 - 關鍵字 "
multipart/ford-data" 與對應的狀態。 - 關鍵字 "
text/plain" 與對應的狀態。
這兩個屬性的失蹤預設值是 application/x-www-form-urlencoded 狀態。
一個元素的編碼型別是這兩個狀態其一。若此元素為提交按鈕且它具有 formenctype 屬性,則此元素的編碼型別是該屬性的狀態,否則此元素的編碼型別是其主表單 enctype 屬性的狀態。
若網頁作者指定內容屬性 target 與 formtarget,則取值必須是合法瀏覽上下文名稱或關鍵字。
如果一个元素是一个提交按钮,且该元素拥有formtarget属性,则该元素的目标为该属性值;或者,如果该元素的所属表单拥有target属性,则为该属性的值;或者,如果Document包含一个拥有target属性的base元素,则为第一个这样的base元素的target属性的值;或者,如果没有这样的元素,则为空字符串。
內容屬性 novalidate 與 formnovalidate 是布林屬性。若存在,代表提交時不驗證該表單。
若一個元素為提交按鈕且它具有 formnovalidate 屬性,或此元素的主表單具有 novalidate 屬性,則此元素的不驗證狀態為真,否則為假。
<form action="editor.cgi" method="post"> <p><label>姓名:<input required name=fn></label></p> <p><label>短文:<textarea required name=essay></textarea></label></p> <p><input type=submit name=submit value="提交短文"></p> <p><input type=submit formnovalidate name=save value="儲存短文"></p> <p><input type=submit formnovalidate name=cancel value="取消"></p> </form>
IDL 屬性 action 必須反映同樣名稱的內容屬性,除非在獲取的時候內容屬性不存在或是屬性的取值為空字串,在這種情形下必須回傳文件的位置。IDL 屬性 target 必須反映同樣名稱的內容屬性。IDL 屬性 method 與 enctype 必須反映同樣名稱的內容屬性,受限於已知取值。IDL 屬性 encoding 必須反映內容屬性 enctype ,限制於已知取值。IDL 屬性 noValidate 必須反映內容屬性 novalidate。IDL 屬性 formAction 必須反映內容屬性 formaction,除非在獲取的時候內容屬性不存在或是屬性的取值為空字串,在這種情形下必須回傳文件的位置。IDL 屬性 formEnctype 必須反映內容屬性 formenctype ,限制於已知取值。IDL 屬性 formMethod 必須反映內容屬性 formmethod ,限制於已知取值。IDL 屬性 formNoValidate 必須反映內容屬性 formnovalidate。IDL 屬性 formTarget 必須反映內容屬性 formtarget。
提交元素方向性
表單控制項元素上的表單控制項 dirname 屬性可以用來提交此元素的方向性,並可以用來命名表單提交時含有這個值的欄位。若網頁作者欲設定此屬性,值必不可為空字串。
文本字段选择API
input和textarea元素在其DOM接口中定义了下列成员,用来对它们的选择进行操作:
void select();
attribute unsigned long selectionStart;
attribute unsigned long selectionEnd;
attribute DOMString selectionDirection;
void setSelectionRange(in unsigned long start, in unsigned long end, in optional DOMString direction);
这些方法和属性暴露和控制了input和textarea文本字段中的选择。
selection . select()
选择文本字段中的所有内容。
selection . selectionStart [ = value ]
返回选择部分起始位置的偏移量。
可以被设置,用来修改选择部分的起始位置。
selection . selectionEnd [ = value ]
返回选择部分结束位置的偏移量。
可以被设置,用来修改选择部分的结束位置。
selection . selectionDirection [ = value ]
返回选择部分的当前方向。
可以被设置,用来修改选择部分的方向。
可能的值包括“forward”、“backward”和“none”。
selection . setSelectionRange(start, end [, direction] )
在给出的方向下,用给出的子字符串修改选择部分。如果忽略了方向,则被重置为平台的默认值(none或forward)。
如果这些方法和属性被用于不适用的input元素,则必须抛出一个INVALID_STATE_ERR异常。否则,必须按需下面的描述执行。
对于input元素,这些方法和属性必须操作该元素的值。对于textarea元素,这些方法和属性必须操作该元素的原始值。
在可能的情况下,用户界面中修改input和textarea元素的文本选中部分的功能必须在本节所描述的DOM API下实现,以便可以全部触发相同的事件等。
input和textarea元素的选中部分拥有一个方向,其值为forward、backward和none。这个方向将在用户对选择部分进行操作时设置。选择部分方向的精确意义有平台决定。
select()方法必须全选文本字段的内容,如果平台支持none方向,则其方向为none,否则方向为forward。用户代理必须以用户交互任务源作为任务源排入一个任务以在该元素上冒泡地触发一个简单事件,其名称为select。
对于selectionStart属性,在获取时,必须返回紧接在选择部分起始位置之后的字符的偏移量(按照逻辑上的顺序)。如果没有选择部分,则必须返回紧接在文本输入光标之后的字符的偏移量(按照逻辑上的顺序)。
在设置时,必须如同调用了setSelectionRange()方法,其中,使用新值作为第一个参数;如果selectionEnd属性的值不小于新值,则使用selectionEnd属性的值作为第二个参数,否则必须使用新值作为第二个参数;使用selectionDirection属性的当前值作为第三个参数。
对于selectionEnd属性,在获取时,必须返回紧接在选择部分结束位置之后的字符的偏移量(按照逻辑上的顺序)。如果没有选择部分,则必须返回紧接在文本输入光标之后的字符的偏移量(按照逻辑上的顺序)。
在设置时,必须如同调用了setSelectionRange()方法,其中,使用selectionStart属性的当前值作为第一个参数;使用新值作为第二个参数;使用selectionDirection属性的当前值作为第三个参数。
对于selectionDirection属性,在获取时,必须返回与当前选择部分方向对应的字符串:如果方向为向前则“forward”;如果方向为向后则“backward”;否则“none”。
在设置时,必须如同调用了setSelectionRange()方法,其中,使用selectionStart属性的当前值作为第一个参数;使用selectionEnd属性的当前值作为第二个参数;使用新值作为第三个参数。
setSelectionRange(start, end, direction)方法必须将文本字段的选择部分设为以第start个位置(按照逻辑上的顺序)的字符为开始、以第(end-1)个位置(按照逻辑上的顺序)的字符为结束的字符串序列。大于文本字段值的长度的参数必须被视为指向文本字段的结尾。如果end小于等于start,则选中部分的开始和结束必须都被指向紧靠偏移量为end的字符之前。对于没有空选择概念的用户代理,必须将光标定位于紧靠偏移量为end的字符之前。如果direction区分大小写地匹配字符串“backward”,则选择部分的方向为向后;如果direction区分大小写地匹配字符串“forward”或平台不支持方向为none,则选择部分的方向为向前;否则选择部分的方向为none(包括参数被忽略)。用户代理必须以用户交互任务源为任务源排入一个任务以在该元素上冒泡地触发一个简单事件,该事件名为select。
对于所有适用这些API的元素,在所有任何时候都拥有一个选择部分或一个文本输入光标(即使元素尚未被渲染)。用户代理应该按照平台的约定确定其初始状态。
在渲染时不可见的字符——例如U+200D零宽度联合字符——仍然算作字符。因此,选择部分可以只包含这些不可见字符,文本输入光标也可以放在这些字符的两侧。
为了获得当前选择的文字,必须执行下列JavaScript代码:
var selectionText = control.value.substring(control.selectionStart, control.selectionEnd);
为了向一个文本控件的开始位置插入一些文本,并保持文本选择部分,则必须保持三个属性:
var oldStart = control.selectionStart; var oldEnd = control.selectionEnd; var oldDirection = control.selectionDirection; var prefix = "http://"; control.value = prefix + control.value; control.setSelectionRange(oldStart + prefix.length, oldEnd + prefix.length, oldDirection);
约束
定义
对于可列的表单相关元素,除非该元素禁止约束验证,都将作为约束验证的候选。(举例说明,如果一个元素是output或fieldset元素,则该元素禁止约束验证。)
一个元素可以定义一个自定义有效性验证错误信息。初始化时,元素必须将其自定义有效性验证错误信息设为空字符串。当其值不是空字符串时,则表示该元素出现自定义错误。这可以通过setCustomValidity()方法设置。用户代理应该在向同于提示控件的问题时使用该自定义有效性验证错误信息。
一个元素可以通过多种途径进行验证。下列列出了表单控件可以处于的有效性状态的列表,这些状态基于约束验证的原因使控件无效。(下面的定义是不规范的;本规范的其他部分精确的定义了何时应该应用这些状态。)
- 出现未填写
- 出现类型不匹配
- 出现格式不匹配
- 出现内容过长
- 出现下溢
- 出现溢出
- 出现步长不匹配
- 出现自定义错误
- 若控件的自定义有效性验证错误信息(通过元素的setCustomValidity()方法设置)不为空字符串。
如果一个元素没有出现上述有效性状态,则该元素满足其约束条件。
约束验证
如果用户代理被要求静态验证form元素表单的约束,则必须执行下列步骤。这些步骤返回一个肯定结果(表单中的全部控件均有效)或一个否定结果(存在无效的控件),以及一个(可能为空的)无效元素的列表。这些步骤不适用脚本程序。
- 设控件集合为所有所属表单为表单的可提交元素的列表,保持树形结构顺序。
- 设无效控件集合为一个元素列表,该列表初始化为空。
- 按照树形结构顺序遍历控件集合的每一个字段,执行下列子步骤:
- 如果无效控件集合为空,则返回肯定的结果并跳过这些步骤。
- 按照树形结构顺序遍历无效控件集合的每一个字段,执行下列子步骤
- 在字段上触发一个简单事件,该事件名为invalid,且可撤销。
- 如果事件没有被撤销,则将字段插入到未处理无效控件集合中。
- 返回否定结果以及在未处理无效控件集合中的元素的列表。
如果用户代理被要求交互式地验证form元素表单的约束,则用户代理必须执行下列步骤:
- 静态验证表单的约束,并且,如果返回否定结果,则设未处理无效控件集合为返回的元素列表。
- 如果返回的结果是肯定的,则返回该结果并跳过这些步骤。
- 向用户报告未处理无效控件集合中给出的至少一个元素约束所出现的问题。用户代理可能会在处理过程中通过对这些元素中的一个执行聚焦步骤使该元素获得焦点,还可能会通过改变滚动条位置或其他行为使该元素进入用户视野。用户代理可能会报告超过一个约束冲突。如果恰当,用户代理可能会合并相关的约束冲突报告(例如,如果在一个组中的多个单选按钮被标为必填项,则只需要报告一个错误)。如果一个空间没有被渲染(例如,其设置了hidden属性)则用户代理可能会报告一个脚本错误。
- 返回否定结果。
约束验证API
element . willValidate
如果该元素在表达提交时将要进行验证,则返回真;否则返回假。
element . setCustomValidity(message)
设置一个自定义错误,使该元素不能通过验证。给出的信息是向用户报告问题时将要展示的消息。
如果攒书为空字符串,则清除自定义错误。
element . validity . valueMissing
如果该元素没有值但是一个必填字段,则返回真;否则返回假。
element . validity . typeMismatch
如果该元素的值的语法不正确,则返回真;否则返回假。
element . validity . patternMismatch
如果该元素的值不匹配指定的格式,则返回真;否则返回假。
element . validity . tooLong
如果该元素的值超过指定的最大长度,则返回真;否则返回假。
element . validity . rangeUnderflow
如果该元素的值低于指定的最小值,则返回真;否则返回假。
element . validity . rangeOverflow
如果该元素的值高于指定的最大值,则返回真;否则返回假。
element . validity . stepMismatch
如果该元素的值不适合由step属性给出的规则,则返回真;否则返回假。
element . validity . customError
如果该元素拥有一个自定义错误,则返回真;否则返回假。
element . validity . valid
如果该元素的值通过验证,则返回真;否则返回假。
valid = element . checkValidity()
如果该元素的值通过验证,则返回真;否则返回假并在该元素上触发一个invalid事件。
element . validationMessage
如果该元素检查过有效性,则返回将会向用户展示的错误信息。
如果一个元素约束验证的候选,则willValidate属性必须返回真,否则必须返回假(例如,如果任意条件禁止表单验证,则返回假)。
当调用setCustomValidity(message)时,必须将自定义有效性验证错误信息为message参数给出的值。
在下面的例子中,脚本程序在一个表单控件每次被编辑时检查其值,一旦其不是一个有效的值,则使用setCustomValidity()方法设置一个恰当的消息。
<label>感觉:<input name=f type="text" oninput="check(this)"></label>
<script>
function check(input) {
if (input.value == "开心" ||
input.value == "不错" ||
input.value == "疲劳") {
input.setCustomValidity('"' + input.value + '"不是一个感觉。');
} else {
// 输入正确,重置错误信息。
input.setCustomValidity('');
}
}
</script>
validity属性必须返回一个ValidityState对象,该对象表示该元素的有效性状态。该对象是活动的,且每次调用该元素的validity属性时必须返回同一个对象。
interface ValidityState {
readonly attribute boolean valueMissing;
readonly attribute boolean typeMismatch;
readonly attribute boolean patternMismatch;
readonly attribute boolean tooLong;
readonly attribute boolean rangeUnderflow;
readonly attribute boolean rangeOverflow;
readonly attribute boolean stepMismatch;
readonly attribute boolean customError;
readonly attribute boolean valid;
};
ValidityState对象拥有下列属性。在获取这些属性时,如果在下面的列表中给出的对应的条件为真,则它们必须返回真,否则必须返回假。
- valudMissing
- 该控件出现未填写。
- typeMismatch
- 该控件出现类型不匹配。
- patternMismatch
- 该控件出现格式不匹配。
- tooLong
- 该控件出现内容过长。
- rangeUnderflow
- 该控件出现下溢。
- rangeOverflow
- 该控件出现溢出。
- stepMismatch
- 该控件出现步长不匹配。
- customError
- 该控件出现自定义错误。
- valid
- 没有其他条件为真。
在调用checkValidity()方法时,如果当前元素是一个约束验证的候选且不满足其约束条件,则用户代理必须在该元素上触发一个简单事件并返回假,该事件名为invalid,且可以被撤销。否则,必须不进行其他操作并返回真。
如果当前元素不是一个约束验证的候选或如果是但其满足其约束条件,则validationMessage属性必须返回空字符串;否则,如果唯一的存在有效性约束问题的表单控件,其必须返回一个用户代理将要将其展示给用户的适当的本地化消息。如果用户代理不会在这种情况下显示一个文本消息(例如,它会显示一个图形化的提示),则该属性必须返回一个恰当的本地化消息,其表示(一个过多个)使该控件不安全的有效性约束。如果当前元素是一个约束验证的候选且出现自定义错误,则返回值应该包括自定义有效性错误消息。
安全性
服务器不应依赖客户端验证。客户端验证可以被恶意用户故意绕开,还可以被使用没有实现这些特性的旧用户代理或自动化工具的用户无意地忽略。约束验证功能只用于改进用户体验,不提供任何形式的安全机制。
表單提交
介绍
此章節不具有規範性
當使用者提交表單時,使用者代理會根據編碼型別將表單的資料專換成相應的結構,並使用給定的方法將該結構送至行動指定的目的地。
拿以下的表單來當例子:
<form action="/find.cgi" method=get> <input type=text name=t> <input type=search name=q> <input type=submit> </form>
若使用者在第一個欄位輸入 "cats",在第二個輸入 "fur",並按下提交按鈕,則使用者代理會載入 /find.cgi?t=cats&q=fur。
另一外面,若以下表單:
<form action="/find.cgi" method=post enctype="multipart/form-data"> <input type=text name=t> <input type=search name=q> <input type=submit> </form>
有了同樣的使用者輸入,提交的結果不太一樣:使用者代理會對給定的網址 HTTP POST 以下的實體內容:
------kYFrd4jNJEgCervE Content-Disposition: form-data; name="t" cats ------kYFrd4jNJEgCervE Content-Disposition: form-data; name="q" fur ------kYFrd4jNJEgCervE--
隱式提交
用户代理可为每个表單建立一個按鈕作为表單的預設按鈕。預設按鈕應該是以樹排序算的第一個所属表單是該form元素的提交按鈕,不過使用者代理可選另一個適合特定平台的按鈕。若平台支援使用者啟動隱式表單提交(舉例來說,在一些平台上,在一個文字欄位有焦距的時候按「輸入鍵」會啟動隱式表單提交),則隱式提交必須觸發預設按鈕的啟動行為。
若表單沒有提交按鈕,則使用者代理必須在隱式提交發生時由 form 元素提交 form 元素自己。
表单提交算法
当一个form元素表单通过某元素提交器(通常是一个按钮)进行提交时,可选的设置一个通过脚本提交标记,用户代理必须执行下列步骤:
- 设表单所属文档为表单所在的Document。
- 如果表单所属文档没有与其关联的浏览器上下文或其浏览器上下文在该Document创建时设置了沙箱中的表单浏览器上下文标记,则不进行任何操作并跳过这些步骤。
- 设表单浏览器上下文为表单所属文档的浏览器上下文。
- 如果表单已经被提交(例如,在处理下两步中触发的事件时表单被再次提交,这可能是由于脚本程序重复的在表单上调用了submit()方法),则跳过这些步骤。这不影响本算法早先的实例。
- 如果没有设置通过脚本提交标记,且提交器元素的未验证状态为假,则交互式验证表单的约束并检查其结果:如果返回否定结果(约束验证的结论是该字段无效,并且可能会通知用户)则跳过这些步骤。
- 如果没有设置通过脚本提交标记,则需要在表单上触发一个简单事件,该事件名为submit,且可以被撤销。如果该事件的默认行为被阻止(例如,如果该事件被撤销)则跳过这些步骤。否则,继续(有效的默认行为是执行提交)。
- 设行为为提交器元素的行为。
- 如果行为是空字符串,则设行为为表单所属文档的文档的地址。
- 相对于提交器元素解释URL行为。如果失败,则跳过这些步骤。否则,设行为是返回的绝对URL。
- 设scheme是返回的绝对URL的<scheme>。
- 设enctype是提交器元素的enctype。
- 设method是提交器元素的method。
- 设target是提交器元素的target。
- 如果在提交表单时,用户指定了一个特点的浏览器上下文,则设目标浏览器上下文为该浏览器上下文。否则,使用目标为名称、表单浏览器上下文为上下文应用通过给出的浏览器上下文名称选择浏览器上下文的规则,并将目标浏览器上下文设为返回的浏览器上下文。
- 如果目标浏览器上下文在上一步被创建,或者如果表单文档尚未被完全加载,则设替换为真,否则设为假。
- 基于每行的第一个单元格中给出的scheme的值在下表中选择一个适当的行。之后,基于每列的第一个单元格中给出的method的值在该行内选择一个适当的单元格。之后,跳转至该表格下面定义的与单元格中的内容同名的步骤。
| GET | POST | |
|---|---|---|
| http | 改变行为URL | 提交实体主体 |
| https | 改变行为URL | 提交实体主体 |
| ftp | 获得行为URL | 获得行为URL |
| javascript | 获得行为URL | 获得行为URL |
| data | 获得行为URL | 发送数据 |
| mailto | 邮寄报头 | 邮寄主体 |
如果scheme没有在表格中列出,则其行为没有被本规范定义。在其他规范的定义了该scheme的情况下,用户代理应该按照其类似于本规范中相似的scheme的方式执行。
行为如下:
- 改变行为URL
- 设query为通过application/x-www-form-urlencoded编码算法对表单数据集进行编码,并解释为一个US-ASCII字符串。
- 设目标为一个新的URL,其等于行为,但其<query>组件被替换为query(如果恰当,加入一个U+003F问号字符(?))。
- 将目标浏览器上下文导航至目标。如果替换为真,则目标浏览器上下文必须以启用替换方式进行导航。
- 提交实体主体
- 设实体主体为通过恰当的表单编码算法对表单数据集进行编码的结果。
- MIME类型有下列确定:
- 如果enctype为application/x-www-form-urlencoded
- 设MIME类型为“application/x-www-form-urlencoded”。
- 如果enctype为multipart/form-data
- 设MIME类型为由字符串“multipart/form-data;”、U+0020空格字符、字符串“boundary=”和由multipart/form-data编码算法产生的multipart/form-data边界字符串连接而成的字符串。
- 如果enctype为text/plain
- 设MIME类型为“text/plain”。
- 否则,将目标浏览器上下文导航至目标,其中以实体主体作为实体主体使用method给出的HTTP方法,其类型为MIME类型。如果替换为真,则目标浏览器上下文必须以启用替换方式进行导航。
- 获得行为URL
- 发送数据
- 设数据为通过恰当的表单编码算法对表单数据集进行编码的结果。
- 如果行为包含字符串“%%%%”(四个U+0025百分号字符),则如果按照US-ASCII进行解释,则%转义数据中不匹配URI通用语法产生的unreserved的所有字节,之后按照US-ASCII字符串处理返回的结果,进一步的%转义所有U+0025百分号字符并用返回的双重转义的字符串替换行为中的第一个“%%%%”。RFC3986
- 否则,如果行为包含字符串“%%”(一行中的两个U+0025百分号字符,并非四个),则如果按照US-ASCII进行解释,则%转义数据中不匹配URI通用语法产生的unreserved的所有字符,之后按照US-ASCII字符串处理返回的结果,用返回的转义字符串替换行为中的第一个“%%”。RFC3986
- 将目标浏览器上下文导航至经过隐式修改的行为(可能为一个data: URL)。如果替换为真,则目标浏览器上下文必须以启用替换方式进行导航。
- 邮寄报头
- 设头部为通过application/a-www-form-urlencoded编码算法对表单数据集进行编码,并解释为一个US-ASCII字符串。
- 将头部中出的的U+002B加号字符(+)替换为字符串“%20”。
- 设目标为行为中从第一个字符到紧靠第一个U+003F分号字符(?)之前的字符(如果存在)或者字符串结尾的所有字符。
- 向目标追加一个单独的U+003F问号字符(?)。
- 向目标追加头部。
- 否则,将目标浏览器上下文导航至目标。如果替换为真,则目标浏览器上下文必须以启用替换方式进行导航。
- 邮寄主体
恰当的表单编码算法由下列条件确定:
- 如果enctype为application/x-www-form-urlencoded
- 如果enctype为multipart-form-data
- 如果enctype为text/plain
构建表单数据集
为表单表单构建表单数据集的算法如下:
- 设控件集合为一个所属表单为表单的所有可提交元素的列表,保持树形结构顺序。
- 设表单数据集为一个“名称-值-类型”元组的列表,初始化为空。
- LOOP:按照树形结构顺序遍历控件集合中的每一个字段,执行下列子步骤:
- 如果满足下列任意条件,则该元素跳过这些子步骤:
- 设类型为字段type IDL属性的值。
- 如果'字段元素是一个type属性处于图片按钮状态的input元素,则进一步嵌套运行下列子步骤:
- 如果字段标记了一个name属性且其值不是空字符串,则设名称为该值并紧跟一个单独的U+002E句号字符(.)。否则,设名称为空字符串。
- 设名称x为将名称和一个单独的U+0078拉丁小写字母X字符(x)串联而组成的字符串。
- 设名称y为将名称和一个单独的U+0079拉丁小写字母Y字符(y)串联而组成的字符串。
- 字段元素是提交器,且在调用当前算法之前用户指定了一个坐标。设x为用户所选择的坐标的X坐标,设y为用户所选择的坐标的y坐标。
- 向表单数据集追加一个实体,其名称为名称x、值为x、类型为类型。
- 向表单数据集追加一个实体,其名称为名称y、值为y、类型为类型。
- 跳过本元素的其余子步骤:如果控件集合中村中其他元素,则返回上方标有LOOP的步骤,否则跳转至下方标有END的步骤。
- 设名称为字段元素的name属性的值。
- 如果字段元素是一个select元素,则对于该select元素中的每一个选择状态为真的HTML5/the-button-element#the-option-element#option元素,向表单数据集中追加一个实体,其名称为名称、值为HTML5/the-button-element#the-option-element#option元素的值、类型为类型。
- 否则,如果字段元素是一个type属性处于复选框状态或单选按钮状态的input元素,则进一步嵌套运行下列子步骤:
- 如果字段元素标记了value属性,则设值为该属性的值;否则,设值为字符串“on”。
- 向表单数据集中追加一个实体,其名称为名称、值为值、类型为类型。
- 否则,如果字段元素是一个type属性处于文件上传状态的input元素,则对于该input元素中选择的每一个文件,向表单数据集中追加一个实体,其名称为名称、值为该文件(包含名称、类型和主体)、类型为类型。如果没有选择文件,则向表单数据集中追加一个实体,其名称为名称、值为空字符串、类型为“application/octet-stream”。
- 否则,如果字段元素是一个object元素:尝试从plugin中获得表单提交值,如果成功,则像表单数据集中追加一个实体,其名称为名称、值为返回的提交值、类型为字符串“object”。
- 否则,向表单数据集中追加一个实体,其名称为名称、值为字段元素的值、类型为类型。
- 如果该元素拥有一个表单控件dirname属性,且该属性的值不是一个空字符,则执行下列子步骤:
- END:返回表单数据集。
URL编码表单数据
application/x-www-form-urlencoded编码算法如下:
- 设结果为空字符串。
- 如果form元素拥有一个accept-charset属性,则综合考虑从表单数据集的名称和值中找到的字符和用户代理所支持的字符编码,在form的accept-charset属性所给出的列表中选择一个兼容ASCII的字符编码。如果没有支持的编码或列表中没有编码,则设选中的字符编码为UTF-8。
否则,如果文档的字符编码是一个兼容ASCII的字符编码,则其为选中的字符编码。
否则,设选中的字符编码为UTF-8。 - 设字符集为选中的字符编码的首选MIME名称。
- 对于表单数据集中的每个实体,执行下列子步骤:
- 如果实体的名称为“_charset_”且其类型为“hidden”,将其值替换为字符集。
- 如果实体的类型为“file”,将其值替换为文件的文件名。
- 对于实体的名称和值中的每个不能用选中的字符编码表示的字符,将该字符替换为一个由一个U+0026与字符(&)、一个U+0023井号字符(#)、一或多个U+0030数字零(0)到U+0039数字九(9)范围内的表示十进制的Unicode码位的字符和一个U+003B分号字符(;)组成的字符串。
- 对于实体的名称和值中的每个字符,应用下列相应的子子步骤:
- 该字符是一个U+0020空格字符
- 将该字符替换为一个单独的U+002B加号字符(+)。
- 如果该字符不属于U+0020、U+002A、U+002D、U+002E、U+0030至U+0039、U+0041至U+005A、U+005F、U+0061至U+007A
- 将该字符替换为下列格式的字符串:
- 设s为一个空字符串。
- 对于该字符按选中的字符编码表示的每个字节b,依次执行下列恰当的子子子步骤:
- 如果该字节属于0x20、0x2A、0x2D、0x2E、0x30至0x39、0x41至0x5A、0x5F、0x61至0x7A
- 向s追加码位等于该字节的Unicode字符。
- 否则
- 向s追加一个U+0025百分号字符(%)紧跟两个在U+0030数字零(0)至U+0039数字九(9)和U+0041罗马大写字符A至U+0046罗马大写字符F范围内的表示该字节的十六进制值(如果必要使用零进行填充)。
- 如果该字节属于0x20、0x2A、0x2D、0x2E、0x30至0x39、0x41至0x5A、0x5F、0x61至0x7A
- 将该字符替换为下列格式的字符串:
- 否则
- 保留该字符
- 该字符是一个U+0020空格字符
- 如果实体的名称为“isindex”,其类型为“text”,且其为表单数据集的第一个实体,则将其值追加至结果中,并跳过本实体的其余子步骤,移至下一个实体(如果存在),或整个算法中的下一步。
- 如果不是第一个实体,向结果中追加一个单独的U+0026与字符(&)。
- 向结果中追加实体的名称。
- 向结果中追加一个单独的U+003D等于号字符(=)。
- 向结果中追加实体的值。
- 将结果按照US-ASCII编码并返回编码后的字节流。
多部分表单数据
multipart/form-data编码算法如下:
- 设结果为空字符串。
- 如果调用该算法时明确了字符编码,则将选中的字符编码设为该编码。(该算法用于其他提供了明确的字符编码的规范,避免像下一段中所描述的依赖form元素。)
否则,如果form元素拥有一个accept-charset属性,则综合考虑从表单数据集的名称和值中找到的字符和用户代理所支持的字符编码,在form的accept-charset属性所给出的列表中选择一个兼容ASCII的字符编码。如果没有支持的编码或列表中没有编码,则设选中的字符编码为UTF-8。
否则,如果文档的字符编码是一个兼容ASCII的字符编码,则其为选中的字符编码。
否则,设选中的字符编码为UTF-8。 - 设字符集为选中的字符编码的首选MIME名称。
- 对于表单数据集中的每个实体,执行下列子步骤:
- 如果实体的名称为“_charset_”且其类型为“hidden”,将其值替换为字符集。
- 对于实体的名称和值中的每个不能用选中的字符编码表示的字符,将该字符替换为一个由一个U+0026与字符(&)、一个U+0023井号字符(#)、一或多个U+0030数字零(0)到U+0039数字九(9)范围内的表示十进制的Unicode码位的字符和一个U+003B分号字符(;)组成的字符串。
- 使用RFC 2388中描述的规则对(现在已经改变的)表单数据集进行编码,从表单返回值:multipart/form-data,并返回编码后的字节流。[RFC2388]
表单数据集中的每个实体是一个字段,实体的名称是字段名、实体的值是字段值。
各部分之间的顺序必须和表单数据集中个字段的顺序相同。拥有相同名称的多个实体必须作为不同的字段进行处理。
对于与非文件字段相对应的multipart/form-data资源产生的部分,禁止其标记一个Content-Type头。它们的名称和值必须使用上面选择的字符编码进行编码(特别的,字段名字没有按照RFC 2388中所建议的转换为一个7位安全编码)。
用于用户代理产生该算法的返回值的边界是multipart/form-data边界字符串。(该值是用于产生由该算法产生的表单提交酬载的MIME类型的。)
纯文本表单数据
text/plain编码算法如下:
- 设结果为空字符串。
- 如果form元素拥有一个accept-charset属性,则综合考虑从表单数据集的名称和值中找到的字符和用户代理所支持的字符编码,在form的accept-charset属性所给出的列表中选择一个字符编码。如果没有支持的编码或列表中没有编码,则设选中的字符编码为UTF-8。
否则,设选中的字符编码为文档的字符编码。 - 设字符集为选中的字符编码的首选MIME名称。
- 如果实体的名称为“_charset_”且其类型为“hidden”,将其值替换为字符集。
- 如果实体的类型为“file”,将其值替换为文件的文件名。
- 对于表单数据集中的每个实体,执行下列子步骤:
- 向结果中追加实体的名称。
- 向结果中追加一个单独的U+003D等于号字符(=)。
- 向结果中追加实体的值。
- 向结果中追加一个U+000D回车(CR)U+000A换行(LF)字符对。
- 使用选择的字符编码对结果进行编码并返回编码返回的字节流。
表單重置
若一个form元素表单被重置,用户代理必须在表单上激活一个简单事件,该事件名为reset,且该事件可取消。之后,如果事件没有被取消,必须调用对每一个所属表单为表单的可重设元素调用重置算法。
每种可重设元素定义了它们的重置算法。这些算法的一部分中对表单控件的修改不计入用户引发的修改(因此,例如,不会触发input事件)。