【发布时间】:2011-12-24 15:30:49
【问题描述】:
我可以在 HTML 表单中使用 PUT 方法将数据从表单发送到服务器吗?
【问题讨论】:
我可以在 HTML 表单中使用 PUT 方法将数据从表单发送到服务器吗?
【问题讨论】:
我写了一个名为“html-form-enhancer”的npm package。通过将其放入您的 HTML 源代码中,它会接管使用除 GET 和 POST 之外的方法提交的表单,并添加 application/json 序列化。
<script type=module" src="html-form-enhancer.js"></script>
<form method="PUT">
...
</form>
【讨论】:
对于使用 laravel 的人
<form method="post" ...>
@csrf
@method('put')
...
</form>
【讨论】:
如果您使用的是 nodejs,您可以安装包 method-override,它允许您使用中间件执行此操作。
文档链接:http://expressjs.com/en/resources/middleware/method-override.html
安装后,我所要做的就是:
var methodOverride = require('method-override')
app.use(methodOverride('_method'))
【讨论】:
_method隐藏字段解决方法
一些网络框架使用了以下简单的技术:
向任何不是 GET 或 POST 的表单添加隐藏的 _method 参数:
<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(),比如显示成功更改或成功删除的消息。
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
【讨论】:
根据HTML standard,您可以不。 method 属性的唯一有效值是 get 和 post,对应于 GET 和 POST HTTP 方法。 <form method="put"> 是无效的 HTML,将被视为 <form>,即发送 GET 请求。
相反,许多框架只是使用 POST 参数来隧道 HTTP 方法:
<form method="post" ...>
<input type="hidden" name="_method" value="put" />
...
当然,这需要服务器端展开。
【讨论】:
不幸的是,现代浏览器不提供对 HTTP PUT 请求的本机支持。要解决此限制,请确保您的 HTML 表单的方法属性为“post”,然后向您的 HTML 表单添加一个方法覆盖参数,如下所示:
<input type="hidden" name="_METHOD" value="PUT"/>
要测试您的请求,您可以使用 Google chrome 扩展程序“Postman”
【讨论】:
XHTML 1.x 表单仅支持 GET 和 POST。 GET 和 POST 是唯一允许的值 “方法”属性。
【讨论】:
我可以在 html 表单中使用“Put”方法将数据从 HTML 表单发送到服务器吗?
是的,您可以,但请记住,它不会导致 PUT 而是 GET 请求。如果您对<form> 标签的method 属性使用无效值,浏览器将使用默认值get。
HTML 表单(直到 HTML 版本 4(,5 Draft)和 XHTML 1)仅支持 GET 和 POST 作为 HTTP 请求方法。一种解决方法是使用隐藏的表单字段通过 POST 通过 POST 隧道传输其他方法,该字段由服务器读取并相应地分派请求。 XHTML 2.0 曾经计划支持表单的 GET、POST、PUT 和 DELETE,但它正在进入 HTML5 的 XHTML5,它不打算支持 PUT。 [update to]
您也可以提供一个表单,但不是提交它,而是使用 JavaScript 的 PUT 方法创建并触发 XMLHttpRequest。
【讨论】:
PUT /resource。
HttpRequest.getParameterMap() 没有返回表单参数。