Answers:
XHTML 1.x表单仅支持GET和POST。GET和POST是“ method”属性的唯一允许值。
根据HTML标准,您不能这样做。方法属性的唯一有效值是get
和post
,它们对应于GET和POST HTTP方法。<form method="put">
是无效的HTML,将被视为<form>
,即发送GET请求。
取而代之的是,许多框架只是使用POST参数来隧道化HTTP方法:
<form method="post" ...>
<input type="hidden" name="_method" value="put" />
...
当然,这需要服务器端解包。
我可以在HTML表单中使用“放置”方法将数据从HTML表单发送到服务器吗?
是的,您可以,但是请记住,它不会导致PUT而是GET请求。如果您为标记的method
属性使用无效值<form>
,则浏览器将使用默认值get
。
HTML表单(最高HTML版本4(第5版草稿)和XHTML 1)仅支持GET和POST作为HTTP请求方法。一种解决方法是使用服务器读取的隐藏表单字段并相应地分派请求,从而通过POST隧道传输其他方法。XHTML 2.0曾经计划支持表单的GET,POST,PUT和DELETE,但是它正在纳入HTML5的XHTML5中,后者不打算支持PUT。[更新至]
您可以选择提供一个表单,但是不用提交表单,而可以使用带有JavaScript的PUT方法创建并触发XMLHttpRequest。
PUT /resource
。
HttpRequest.getParameterMap()
没有返回表单参数。
_method
隐藏字段的解决方法
一些Web框架使用以下简单技术:
将隐藏_method
参数添加到非GET或POST的任何形式:
<input type="hidden" name="_method" value="PUT">
这可以通过HTML创建帮助器方法在框架中自动完成。
将实际的表单方法固定为POST(<form method="post"
)
_method
在服务器上进行处理,并且完全像发送该方法而不是实际的POST一样
您可以通过以下方式实现此目的:
form_tag
@method("PATCH")
纯HTML不可能实现的原因/历史:https : //softwareengineering.stackexchange.com/questions/114156/why-there-are-no-put-and-delete-methods-in-html-forms
@method("PATCH")
POST
不是您实际需要的。
要设置方法PUT和DELETE,请执行以下操作:
<form
method="PUT"
action="domain/route/param?query=value"
>
<input type="hidden" name="delete_id" value="1" />
<input type="hidden" name="put_id" value="1" />
<input type="text" name="put_name" value="content_or_not" />
<div>
<button name="update_data">Save changes</button>
<button name="remove_data">Remove</button>
</div>
</form>
<hr>
<form
method="DELETE"
action="domain/route/param?query=value"
>
<input type="hidden" name="delete_id" value="1" />
<input type="text" name="delete_name" value="content_or_not" />
<button name="delete_data">Remove item</button>
</form>
然后,JS会执行所需的方法:
<script>
var putMethod = ( event ) => {
// Prevent redirection of Form Click
event.preventDefault();
var target = event.target;
while ( target.tagName != "FORM" ) {
target = target.parentElement;
} // While the target is not te FORM tag, it looks for the parent element
// The action attribute provides the request URL
var url = target.getAttribute( "action" );
// Collect Form Data by prefix "put_" on name attribute
var bodyForm = target.querySelectorAll( "[name^=put_]");
var body = {};
bodyForm.forEach( element => {
// I used split to separate prefix from worth name attribute
var nameArray = element.getAttribute( "name" ).split( "_" );
var name = nameArray[ nameArray.length - 1 ];
if ( element.tagName != "TEXTAREA" ) {
var value = element.getAttribute( "value" );
} else {
// if element is textarea, value attribute may return null or undefined
var value = element.innerHTML;
}
// all elements with name="put_*" has value registered in body object
body[ name ] = value;
} );
var xhr = new XMLHttpRequest();
xhr.open( "PUT", url );
xhr.setRequestHeader( "Content-Type", "application/json" );
xhr.onload = () => {
if ( xhr.status === 200 ) {
// reload() uses cache, reload( true ) force no-cache. I reload the page to make "redirects normal effect" of HTML form when submit. You can manipulate DOM instead.
location.reload( true );
} else {
console.log( xhr.status, xhr.responseText );
}
}
xhr.send( body );
}
var deleteMethod = ( event ) => {
event.preventDefault();
var confirm = window.confirm( "Certeza em deletar este conteúdo?" );
if ( confirm ) {
var target = event.target;
while ( target.tagName != "FORM" ) {
target = target.parentElement;
}
var url = target.getAttribute( "action" );
var xhr = new XMLHttpRequest();
xhr.open( "DELETE", url );
xhr.setRequestHeader( "Content-Type", "application/json" );
xhr.onload = () => {
if ( xhr.status === 200 ) {
location.reload( true );
console.log( xhr.responseText );
} else {
console.log( xhr.status, xhr.responseText );
}
}
xhr.send();
}
}
</script>
定义了这些功能后,我将事件监听器添加到发出表单方法请求的按钮上:
<script>
document.querySelectorAll( "[name=update_data], [name=delete_data]" ).forEach( element => {
var button = element;
var form = element;
while ( form.tagName != "FORM" ) {
form = form.parentElement;
}
var method = form.getAttribute( "method" );
if ( method == "PUT" ) {
button.addEventListener( "click", putMethod );
}
if ( method == "DELETE" ) {
button.addEventListener( "click", deleteMethod );
}
} );
</script>
对于PUT表单上的删除按钮:
<script>
document.querySelectorAll( "[name=remove_data]" ).forEach( element => {
var button = element;
button.addEventListener( "click", deleteMethod );
</script>
_------------
本文https://blog.garstasio.com/you-dont-need-jquery/ajax/对我有很大帮助!
除此之外,您可以根据需要设置postMethod函数和getMethod来处理POST和GET提交方法,而不是浏览器的默认行为。您可以执行任何您想使用的操作location.reload()
,例如显示成功更改或成功删除的消息。
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
JSFiddle:https://jsfiddle.net/enriquerene/d6jvw52t/53/