เป็นการดีที่จะใช้ URL ที่ว่างเปล่าสำหรับแอตทริบิวต์การกระทำของฟอร์ม HTML หรือไม่ (การกระทำ =“”)


279

ฉันสงสัยว่าใครสามารถตอบกลับ "แนวปฏิบัติที่ดีที่สุด" เพื่อใช้การกระทำแบบฟอร์ม HTML เปล่าเพื่อโพสต์กลับไปที่หน้าปัจจุบัน

มีโพสต์ถามว่าการกระทำแบบฟอร์ม HTML ว่างเปล่าทำอะไรที่นี่และบางหน้าเช่นนี้แนะนำว่ามันดี แต่ฉันอยากจะรู้ว่าคนอื่นคิดอย่างไร


7
แนะนำให้ใช้แท็ก "แนวทางปฏิบัติที่ดีที่สุด" กับสิ่งนี้
Will Morgan

หากต้องการยืนยันเป็นสองเท่าให้เว้นว่างการกระทำหรือเพียงแค่ไม่พูดถึงการกระทำเลย (เช่น<form name="xyz" >) มันจะส่งการกระทำด้วยตัวเอง
lwpro2

11
ไม่รวมแอ็ตทริบิวต์การดำเนินการเปิดหน้าเว็บที่มีiframe clickjacking attack เช่นหน้าเว็บที่ผู้โจมตีล้อมหน้าของคุณใน iframe และ URL iframe จะมีพารามิเตอร์ข้อความค้นหาที่มีชื่อเดียวกันกับฟิลด์แบบฟอร์ม เมื่อมีการส่งแบบฟอร์มค่าแบบสอบถามจะถูกแทรกลงในฐานข้อมูลดังนั้นข้อมูลการระบุของผู้ใช้ (อีเมลที่อยู่และอื่น ๆ ) จึงถูกบุกรุก
Paul Sweatte

ดังนั้นวิธีที่ถูกต้องและปลอดภัยในการส่งแบบฟอร์มไปยังหน้าปัจจุบันคืออะไร?
Costa

คำตอบ:


268

สิ่งที่ดีที่สุดที่คุณทำได้คือออกจากแอ็ตทริบิวต์การกระทำโดยสิ้นเชิง หากคุณไม่ได้กรอกฟอร์มจะถูกส่งไปยังที่อยู่ของเอกสารเช่นหน้าเดียวกัน

นอกจากนี้ยังเป็นไปได้ที่จะปล่อยให้มันว่างเปล่าและเบราว์เซอร์ใดก็ตามที่ใช้อัลกอริทึมการส่งแบบฟอร์มของ HTMLจะถือว่ามันเทียบเท่ากับที่อยู่ของเอกสาร

8.ขอให้การดำเนินการเป็นส่วนส่งของการกระทำ

9.หากการดำเนินการคือสตริงที่ว่างเปล่าให้การดำเนินการเป็นที่อยู่ของเอกสาร

หมายเหตุ: ขั้นตอนนี้เป็นการละเมิดโดยเจตนาของ RFC 3986 ซึ่งจะต้องมีการประมวลผล URL พื้นฐานที่นี่ การละเมิดนี้ได้รับแรงบันดาลใจจากความปรารถนาที่จะเข้ากันได้กับเนื้อหาดั้งเดิม [RFC3986]

นี้แน่นอนทำงานในเบราว์เซอร์ในปัจจุบันทั้งหมด แต่อาจไม่ทำงานตามที่คาดไว้ในเบราว์เซอร์รุ่นเก่าบางรุ่น ( " เบราว์เซอร์ทำสิ่งแปลกที่มีการกระทำที่ว่างเปล่า =" "แอตทริบิวต์ " ) ซึ่งเป็นเหตุผลที่สเปคขออุปสรรคเขียนออกจากมันว่างเปล่า :

actionและformactionแอตทริบิวต์เนื้อหาถ้าระบุต้องมีค่าที่เป็นURL ไม่ว่างเปล่าที่ถูกต้องที่อาจเกิดขึ้นล้อมรอบด้วยช่องว่าง


12
อาจมีการเปลี่ยนแปลงตั้งแต่คำตอบของคุณ (เกือบสามปีแล้ว) แต่ ณ วันนี้ HTML5 ไม่อนุญาตaction=""- ดูคำตอบของฉัน ...
derobert

2
@derobert ขอบคุณ สิ่งนี้อาจไม่เปลี่ยนแปลง ฉันได้เปลี่ยนคำตอบเพื่อให้สะท้อนถึงสิ่งที่สเป็คพูด
Mercator

73

ที่จริงส่วนย่อยแบบฟอร์มการส่งร่าง HTML5 action=""ปัจจุบันไม่อนุญาตให้ มันขัดกับสเป็ค

actionและformactionแอตทริบิวต์เนื้อหาถ้าระบุต้องมีค่าที่ถูกต้องไม่ว่างเปล่า URL ที่อาจเกิดขึ้นล้อมรอบด้วยช่องว่าง (เน้นเพิ่ม)

ส่วนที่ยกมาในคำตอบของ Mercatorเป็นความต้องการในการใช้งานที่ไม่ได้เขียน ผู้เขียนจะต้องปฏิบัติตามข้อกำหนดของผู้แต่ง หากต้องการอ้างอิงวิธีอ่านข้อมูลจำเพาะนี้ :

โดยเฉพาะอย่างยิ่งมีข้อกำหนดความสอดคล้องที่ใช้กับผู้ผลิตเช่นผู้แต่งและเอกสารที่พวกเขาสร้างและมีข้อกำหนดความสอดคล้องที่ใช้กับผู้บริโภคเช่นเว็บเบราว์เซอร์ พวกเขาสามารถแยกแยะได้ด้วยสิ่งที่พวกเขาต้องการ: ข้อกำหนดของผู้ผลิตระบุสิ่งที่ได้รับอนุญาตในขณะที่ข้อกำหนดของผู้บริโภคระบุว่าซอฟต์แวร์ต้องทำหน้าที่อย่างไร

การเปลี่ยนแปลงจาก HTML4 ซึ่งอนุญาต URL ที่ว่างเปล่าเกิดขึ้นเนื่องจาก“ เบราว์เซอร์ทำสิ่งแปลก ๆ ที่มีaction=""แอตทริบิวต์ว่างเปล่า ” เมื่อพิจารณาถึงเหตุผลของการเปลี่ยนแปลงน่าจะดีที่สุดที่จะไม่ทำเช่นนั้นใน HTML4


มันอนุญาตให้มีการขาดทั้งหมดของactionคุณลักษณะทั้งหมดเพื่อระบุแบบฟอร์มที่ควรส่งไปยังที่อยู่เอกสารหรือไม่ ดูเหมือนว่าเพราะมันบอกว่า "ถ้าระบุไว้"
Kerrick

2
@ Kerrick ใช่ฉันเชื่อว่า HTML5 อนุญาตให้ละเว้นแอตทริบิวต์การกระทำทั้งหมดและเริ่มต้นให้เป็นสตริงว่างเปล่า HTML4 ไม่ได้ระบุการกระทำตามที่ต้องการ
Derobert

ฉันเห็นด้วยกับ @Kerrick อนุญาตให้ละเว้นแอตทริบิวต์การกระทำ อ่านที่ HTML5 ปัจจุบันดูเหมือนว่าไม่อนุญาตให้ใช้สตริงที่ว่างเปล่า แต่ไม่มีแอตทริบิวต์ที่ได้รับอนุญาต แต่ในกรณีใด ๆ ด้วยเหตุผลด้านความเข้ากันได้เราขอแนะนำให้คุณใส่แอตทริบิวต์ "action" ไว้เสมอและกรอก URL ที่ไม่ว่างเปล่า (แนวทางปฏิบัติที่ดีเป็นวิธีที่ดีที่สุดเสมอ)
serfer2 2

หนึ่ง gotcha ที่อาจเกิดขึ้น: AngularJS จะป้องกันการส่งแบบฟอร์มโดยไม่มีแอตทริบิวต์การกระทำ อาจไม่ใช่ปัญหาทั่วไป แต่ใช้เวลาพอสมควรที่จะเข้าใจว่าทำไมบางส่วนของเว็บไซต์มรดกเริ่มแตก
Asmor

18

ไม่รวมแอททริบิวต์ action จะเปิดหน้าเว็บได้มากถึงiframe clickjacking attack ซึ่งเกี่ยวข้องกับขั้นตอนง่ายๆ:

  • ผู้โจมตีล้อมหน้าของคุณใน iframe
  • URL iframe มีพารามิเตอร์แบบสอบถามที่มีชื่อเดียวกันกับเขตข้อมูลฟอร์ม
  • เมื่อมีการส่งแบบฟอร์มค่าแบบสอบถามจะถูกแทรกลงในฐานข้อมูล
  • ข้อมูลการระบุตัวตนของผู้ใช้ (อีเมลที่อยู่ ฯลฯ ) ถูกโจมตี

อ้างอิง


2
URL iframe ไม่มีพารามิเตอร์ GET หรือไม่ในขณะที่แบบฟอร์มมักจะส่งโดยใช้ POST ดังนั้นหากเว็บไซต์เกี่ยวข้องกับพารามิเตอร์ POST เท่านั้นก็ไม่น่าจะมีปัญหาใช่ไหม อย่างน้อยฉันมักจะใช้อาร์เรย์ $ _POST ใน PHP เฉพาะเมื่อประมวลผลแบบฟอร์ม
Calmarius

2
@Calarius ใช่ใช้$_POSTแทน$_REQUESTเพื่อหลีกเลี่ยงปัญหานี้ หากใช้รหัสกรอบ$_REQUESTให้ใช้มือปราบ iframe
พอล Sweatte

17

สิ่งนี้จะตรวจสอบกับ HTML5

<form action="#">

4
ฉันไม่ได้ลอง แต่แนวคิดจะไม่เลื่อนไปที่ด้านบนของหน้าหลังจากส่ง?
Matt Mitchell

2
คุณใช้action="."ไม่ได้เหรอ
s427

3
การกระทำ = "?" ทำงานได้ดีเช่นกัน มันตรวจสอบและชี้ไปที่หน้าปัจจุบันโดยไม่ต้องและสอบถามข้อมูลสตริง
Chris Broski

5
action="."เป็นความคิดที่ดีสำหรับกรณีทั่วไป URL ที่เหมือนถูกแมปไปเพียงexample.com/login example.com/
Torsten Bronger

1
คำตอบนี้ใช้ได้เฉพาะเมื่อผู้ใช้ต้องการเลื่อนไปที่ด้านบนของหน้า
Buts

9

ใน HTML 5 action=""ไม่รองรับดังนั้นอย่าทำเช่นนี้ การปฏิบัติที่ไม่ดี

หากคุณปฏิเสธการดำเนินการโดยสิ้นเชิง แต่จะส่งไปที่หน้าเดียวกันโดยค่าเริ่มต้นฉันเชื่อว่านี่เป็นวิธีปฏิบัติที่ดีที่สุด:

<form>This will submit to the current page</form>

หากคุณกำลังใช้แบบฟอร์ม php คุณอาจต้องพิจารณาสิ่งต่อไปนี้ อ่านเพิ่มเติมได้ที่นี่

<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">

หรือคุณอาจใช้การ#จำไว้ว่าสิ่งนี้จะทำหน้าที่เป็นตัวยึดและเลื่อนไปที่ด้านบนของหน้า

<form action="#">

ต้องการที่จะเข้าใจว่าทำไมใครบางคนลงคะแนนให้คำตอบนี้
Buts

คุณปิดใช้งานแอ็ตทริบิวต์ action แล้วแบบฟอร์มยังคงเปิดให้หาประโยชน์หารายละเอียดในหน้าเฟิร์สต์บนลิงก์หรือไม่
Richard Young Young

@RichardYoung ขออภัยฉันไม่เข้าใจคำถามของคุณ กรุณาใช้ถ้อยคำใหม่
Buts

1
แฮกเกอร์สามารถใช้ตัวแปร $ _SERVER ["PHP_SELF"] หากมีการใช้ PHP_SELF ในหน้าเว็บของคุณผู้ใช้สามารถป้อนเครื่องหมายสแลช (/) และคำสั่ง Cross Site Scripting (XSS) เพื่อดำเนินการ หากคุณไม่ใช้แอททริบิวต์แอ็คชั่นคุณยังคงมีความเสี่ยงอยู่หรือไม่?
Richard Young Young

ใช่คุณเป็น แอ็ตทริบิวต์ action สามารถเพิ่มกลับในฝั่งไคลเอ็นต์และกำหนดค่าตัวเลือกใด ๆ อย่างไรก็ตามการใช้htmlspecialchars()ฟังก์ชั่นนี้จะหยุดผู้คนจากคนที่ใช้ php script ของคุณกับคุณ
Buts

4

ปกติฉันจะใช้ action = "" ซึ่งเป็น XHTML ที่ถูกต้องและเก็บข้อมูล GET ไว้ใน URL


4
แต่ตัวอย่างเช่นในฟอรัมของฉันฉันจะมี URL: thread.php? id = 12 & page = 6 และมีแบบฟอร์ม POST ที่ด้านล่างของหน้าเพื่อเพิ่มความคิดเห็นและฉันต้องการข้อมูล GET ดังนั้น PHP รู้หัวข้อที่จะเพิ่มความคิดเห็น
Juddling

20
GET เป็นวิธีการเริ่มต้นสำหรับรูปแบบ - มันแทบจะเป็นสิ่งที่ไม่ดี ;-) w3.org/TR/html401/interact/forms.html#adef-method
NickFitz

5
การใช้ GET ในรูปแบบเป็นสิ่งที่ไม่ดี หากผู้ใช้โหลดซ้ำหน้าหลังจากส่งอาจมีผลกระทบที่ไม่ตั้งใจ อย่างไรก็ตามหากใช้ POST เบราว์เซอร์จะเตือนเกี่ยวกับการส่งข้อมูลเดิมอีกครั้ง
จะ Sheppard

22
@ WillSheppard ฉันไม่เห็นด้วย คุณไม่สามารถทำแบบผ้าห่มได้ ทุกอย่างขึ้นอยู่กับสิ่งที่แบบฟอร์มทำ คุณควรใช้ POST สำหรับทุกสิ่งที่ดำเนินการ (เช่นการแทรกโพสต์ใหม่ในฟอรัม) แต่รับ GET สำหรับทุกอย่าง (เช่นช่องค้นหาหรือใช้แบบฟอร์มสำหรับการนำทาง) หลังจาก POST สำเร็จสคริปต์ควรเปลี่ยนเส้นทางเบราว์เซอร์เพื่อป้องกันไม่ให้ผู้ใช้ส่งข้อมูลอีกครั้ง
Mike

3
PS ไม่ใช่ทุกเบราว์เซอร์ที่เตือนผู้ใช้ในการส่งข้อมูล POST อีกครั้ง (เช่น Opera)
Mike

4

ฉันคิดว่าเป็นการดีที่สุดที่จะระบุอย่างชัดเจนว่าแบบฟอร์มโพสต์ที่ใด หากคุณต้องการความปลอดภัยโดยสิ้นเชิงให้ป้อน URL เดียวกันกับที่มีการเปิดฟอร์มในแอ็ตทริบิวต์การดำเนินการหากคุณต้องการให้มันส่งกลับมาที่ตัวเอง แม้ว่าเบราว์เซอร์กระแสหลัก""จะประเมินเป็นหน้าเดียวกันคุณไม่สามารถรับประกันได้ว่าเบราว์เซอร์ที่ไม่ใช่กระแสหลักจะทำเช่นนั้น

และแน่นอนว่า URL ทั้งหมดรวมถึงข้อมูล GET เช่น Juddling ชี้ให้เห็น


2

เพียงแค่ใช้

?

<form action="?" method="post" enctype="multipart/form-data" name="myForm" id="myForm">

ไม่ละเมิดมาตรฐาน HTML5


ฉันไม่ได้ลงคะแนน แต่วิธีการของคุณจะลดgetพารามิเตอร์ทั้งหมด แบบฟอร์มใน URL ต่อไปนี้จะแตกexample.com/update_user?user_id=1เพราะแบบฟอร์มจะส่งถึงexample.com/update_user?
vikki

1

ฉันเคยทำสิ่งนี้บ่อยๆเมื่อฉันทำงานกับ Classic ASP โดยปกติฉันจะใช้เมื่อต้องการการตรวจสอบความถูกต้องฝั่งเซิร์ฟเวอร์สำหรับการป้อนข้อมูลบางอย่าง (ก่อนวัน AJAX) จุดประสงค์หลักที่ฉันเห็นคือมันไม่ได้แยกตรรกะการเขียนโปรแกรมจากงานนำเสนอที่ระดับไฟล์


1
ทำไมจะไม่ล่ะ? ฉันคิดว่ามันไม่ได้เชื่อมต่อ ฉันสามารถมีแบบฟอร์มโพสต์ข้อมูลไปยังหน้าเดียวกันและสร้างหน้านี้ด้วยการแยกตัวควบคุมและมุมมองที่เหมาะสม
markus

1

ฉันใช้เพื่อไม่ระบุแอตทริบิวต์การกระทำเลย จริงๆแล้วมันเป็นวิธีการที่กรอบของฉันได้รับการออกแบบทุกหน้าได้รับการส่งกลับไปยังที่อยู่เดียวกันแน่นอน แต่วันนี้ฉันค้นพบปัญหา บางครั้งฉันยืมค่าแอ็ตทริบิวต์การดำเนินการเพื่อโทรหาแบ็คกราวน์ (ฉันเดาว่าบางคนตั้งชื่อพวกเขาว่า AJAX) ดังนั้นฉันจึงพบว่า IE เก็บค่าแอ็ตทริบิวต์การกระทำว่าว่างเปล่าหากไม่ได้ระบุแอททริบิวต์การกระทำ มันค่อนข้างแปลกในความเข้าใจของฉันเพราะถ้าไม่มีการระบุแอ็ตทริบิวต์การดำเนินการจาวาสคริปต์ JavaScript จะต้องไม่ถูกกำหนดอย่างน้อย อย่างไรก็ตามประเด็นของฉันคือก่อนที่คุณจะเลือกแนวทางปฏิบัติที่ดีที่สุดที่คุณต้องเข้าใจบริบทเพิ่มเติมเช่นคุณจะใช้คุณลักษณะใน JavaScript หรือไม่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.