美文网首页
HTML
只支持 GET 和 POST!

HTML 只支持 GET 和 POST!

作者: AlphaHinex | 来源:发表于2021-08-22 11:08 被阅读0次

原文地址:https://alphahinex.github.io/2021/08/22/hidden-http-method-filter/

cover

description: "这很不 RESTful"
date: 2021.08.22 10:26
categories:
- Spring
tags: [HTML, Spring]
keywords: RESTful, HTML, form, method, get, post, delete, put, HiddenHttpMethodFilter, MultipartFilter


HTML form method

在 Web 开发中,常规的提交数据方式为使用 form 表单,例如:

<form action="" method="get" class="form-example">
  <div class="form-example">
    <label for="name">Enter your name: </label>
    <input type="text" name="name" id="name" required>
  </div>
  <div class="form-example">
    <label for="email">Enter your email: </label>
    <input type="email" name="email" id="email" required>
  </div>
  <div class="form-example">
    <input type="submit" value="Subscribe!">
  </div>
</form>

form 中各属性的值,可参考 MDN 文档,其中,method 属性支持的值如下:

method

The HTTP method to submit the form with. Possible (case insensitive) values:

  • post: The POST method; form data sent as the request body.
  • get: The GET method; form data appended to the action URL with a ? separator. Use this method when the form has no side-effects.
  • dialog: When the form is inside a <dialog>, closes the dialog on submission.

这在 JSP 时代通常只使用 getpost 两种 method 时并无大碍,但在 RESTful 盛行的今日,无疑显得很不和谐。

Spring 的解决方式

在 Spring 提供的 form 标签库 中,对 HTML 中的 form 进行了全面的丰富,在 JSP 页面中引入 taglib:

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

之后可以通过 <form:form> 的方式使用,如:

<form:form method="delete">
    <p class="submit"><input type="submit" value="Delete Pet"/></p>
</form:form>

<form:form> 最终也会被服务端渲染为 <form>,那为什么这里的 method 不再局限于 HTML 规范中要求的值呢?

HiddenHttpMethodFilter

在 Spring 中,使用了一种 HTTP Method 转换方式:以上面代码片段为例,实际提交的表单的 method 是 POST 类型的,同时在请求参数中包含了一个隐藏的属性,默认为 _method,里面存放了真正的 method —— DELETE

在服务端,接收请求时,有一个 HiddenHttpMethodFilter,负责将请求的 method 修改为隐藏属性中的实际 method,再传入后续处理流程,以使得我们的 Controller 能够使用 @DeleteMapping 接收到请求。

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
        throws ServletException, IOException {

    HttpServletRequest requestToUse = request;

    if ("POST".equals(request.getMethod()) && request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE) == null) {
        String paramValue = request.getParameter(this.methodParam);
        if (StringUtils.hasLength(paramValue)) {
            String method = paramValue.toUpperCase(Locale.ENGLISH);
            if (ALLOWED_METHODS.contains(method)) {
                requestToUse = new HttpMethodRequestWrapper(request, method);
            }
        }
    }

    filterChain.doFilter(requestToUse, response);
}

一切都还挺美好的,直到……

上传文件为空

Spring 中,需要上传文件时,又同时使用了 HiddenHttpMethodFilter,如果配置不当,大概率会遇到 Controller 中接到的 MultipartFile 为空的情况。在 HiddenHttpMethodFilter源码 中,其实已经说明了这个问题:

NOTE: This filter needs to run after multipart processing in case of a multipart POST request, due to its inherent need for checking a POST body parameter. So typically, put a Spring org.springframework.web.multipart.support.MultipartFilter before this HiddenHttpMethodFilter in your web.xml filter chain.

只需要让处理上传文件的 Filter 先于处理 HTTP method 隐藏属性的 Filter 即可。

相关文章

  • HTML 只支持 GET 和 POST!

    原文地址:https://alphahinex.github.io/2021/08/22/hidden-http-...

  • form标签、input标签与table标签

    form标签 和 的区别:区别在与a发起的get请求。form发起的是get或post请求(不支持PUT)。get...

  • 前端03-HTML续

    HTML续 form action:指定提交地址 method:提交方法,get和post等 enctype:指定...

  • php文件上传

    一.首先看看html的form表单结构 form表单需要定义method的属性的值,可以为2种:get和post;...

  • 基础知识

    8:html的form默认的提交方式是get,get方式会导致中文乱码。重点:get页面可以保存,post页面不能...

  • 1.改变url的地址: location.href='b.html', form表单提交(get, post), ...

  • http的contentType理解

    常见的类型由以下几种 1 application/x-www-form-urlencoded支持GET/POST等...

  • html 3 form和input,get和post

    form表单 get 和post:1~数据提交方式不同,get提交URL可见,post看不见 2~get提交少量数...

  • spring mvc 对 http请求 put delete处理

    浏览器form表单只支持GET与POST请求,而DELETE、PUT等method并不支持,spring3.0添加...

  • HiddenHttpMethodFilter

    浏览器form表单只支持GET与POST请求,而DELETE、PUT等method并不支持,spring3.0添加...

网友评论

      本文标题:HTML 只支持 GET 和 POST!

      本文链接:https://www.haomeiwen.com/subject/ebsfiltx.html