不要把你的input元素設定為“action”或“submit”

abell123發表於2014-05-27

大多數的瀏覽器都有一個嚴格意義上來說不能算作bug的bug。實際上,瀏覽器的本意是讓你的工作變得更簡單,但是如果你(或者其他人)恰好以某種方式(其實是錯誤的方式)來寫HTML程式碼的話,就會完全觸發該問題。特別的,如果你指定input標籤的id或者name屬性值為“action”或“submit”,你可能就會觸發非常隱藏的bug。

關於該“Bug”的介紹

去年我通讀了John Resig 和Bear Bibeault著作的《Secrets of the JavaScript Ninja》一書。順便說一下,如果你想寫高效、優雅的javascript程式碼,這絕對是一本非常棒的書。不管怎麼樣,在第11章,某些內容吸引了我的注意力。如果你在form表單裡有一個擁有id和/或name屬性的input元素,那麼你可以直接通過form元素的某些屬性獲取到該input元素,該特性被作者稱為是“貪婪的ID”(greedy IDs)。

這真是一個相當酷的想法,但是這並不是很有必要,因為通過元素的id或者name屬性來獲取元素也是很容易的。而且,要注意一個非常重要的事實:如果form元素的某個屬性名和input元素的id/name值一樣,那麼該form的屬性就會被input元素的屬性值所覆蓋。

如果你的input元素的id/name屬性值被設定為了“action”或“submit”,然後你嘗試使用javascript控制提交,那麼此時就會變得極其悲劇。現在,如果你想知道form表單資料提交 (通過 form.action提交)的URL,或者你只是想通過寫js程式碼的方式來提交(通過form.submit提交),那麼你將會分別得到一個錯誤的值和直接報錯。

解決方案

我從來沒想過我會遇到這個問題,但是我還是碰到了。也許解決該問題的最簡單的方法是改寫你的input,但是不幸的是有時你可能拿不到HTML程式碼,而有時你根本不會去拿。而且其他的程式碼也可能依賴於id/name來做一些事情。因此,如果你沒法去直接修改HTML程式碼,這裡還有其他的解決方案。

這種解決方案只能解決form表單元素的屬性值是函式的情形。任意值不是函式的屬性都將不起作用,即使你嘗試用javascript程式碼去動態修改input元素的id/name屬性也毫無用處。不管怎麼樣,重寫值是函式的屬性(比如submit),從元素物件的原型獲取函式,並將該函式以你想執行的form表單元素為執行環境來執行就能解決問題。

我並沒有在老版本的瀏覽器做測試,但是它應該在對較老HTML4支援較好的瀏覽器上都能正常執行,因為HTMLFormElement最初是在DOM Level 1規範中被指定的。

結論

在書中沒有給出解決方案我感到有些驚訝。他們只是多少提到了說我們要避免使用這些ids/names(指action、submit等):

“幸運的是,通過避免使用和標準的屬性名衝突的較簡單的id值,我們在自己的標記中可以避免這個問題,同時我們鼓勵其他人也這麼做。特別是id和name的值要避免用submit,這是一個導致讓人費解的bug並令人沮喪的問題的常見來源。”

雖然這的確是一個合理的建議,正因如此我把它作為了文章的標題,但這種情況並不總是可以避免的,因此有一種簡單的能解決一部分問題的方案總是好的。但無論如何,我希望你永遠用不到這種解決方案。願上帝保佑,祝你程式設計快樂!

打賞支援我翻譯更多好文章,謝謝!

打賞譯者

打賞支援我翻譯更多好文章,謝謝!

任選一種支付方式

不要把你的input元素設定為“action”或“submit” 不要把你的input元素設定為“action”或“submit”

相關文章