关于405状态码的奇怪错误(ajax和springmvc)

今天在做一个ajax和springmvc交互的时候,出现了一个很奇怪的错误
我直接贴出相关代码,请大家帮我看看
前端test1.html,就是一个表单的提交

<form  id="login" method="post">
    Email<input type="text" id="inputEmail3" name="email" placeholder="Email">
    Password<input type="password" id="inputPassword3" name="password" placeholder="Password">
    <button type="submit"onclick="sign()">Sign in</button>
</form>

<script>
    function sign() {
        var loginData = $("#login").serialize()//表单数据
        $.ajax({
            url: "/test04",
            data: loginData,
            type: 'POST',
            success: function (resp) {
                if (resp == "success") {
                    window.location.href = "/test.html"//test.html我就不再贴出,就一行helloword
                }
            }
        })
    }
</script>

后端controller

@PostMapping("/test04")
@ResponseBody
public String Test04(@RequestParam("email") String email,
                                @RequestParam("password") String password){

        System.out.println(email + " " + password);//可以正常输出
        return "success";
    }

视图跳转配置类

@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
    @Override//自定义视图跳转
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("test.html").setViewName("test");
        registry.addViewController("test1.html").setViewName("test1");
    }
}

浏览器输入localhost:8080/test1.html
填完表单数据后,点击sign in,第一次出现如下情况

img

第二次我再次访问localhost:8080/test1.html的时候

img

填完表单数据后,就可以正常跳转到hello word的页面了!真的好奇怪啊!

img

如果我将上述的controller换成如下,那么就直接变成405了,不管访问多少次。RequestBody 注解是用来接收前端的json数据的,可是 var loginData = $("#login").serialize()这句不就是序列化成字符串吗,我不太理解。

@PostMapping("/test04")
@ResponseBody
public String Test04(@RequestBody People people){
        System.out.println(people);//不可以输出
        return "success";
    }

如果将requestbody注解去掉,变成public String Test04(People people),那么将会出现我写的上面第一种的情况,也就是第一个次访问是405,后续访问就正常了。希望大家能帮我解答,请大家喝元气森林!

405一般都是说前后端请求不匹配,比如后端post请求前端却用了get请求,你既然用了ajax来请求就要完全避免表单会发生表单它自己的请求,建议:把表单form标签简化,什么属性也不加,特别是button那个提交按钮最好不要留着type=“submit”这样和click事件的冲突

json字符串数据和序列化成字符串是两个东西

JSON.stringfy():将信息序列化为JSON
JSON.parse() :将JSON反序列化为JavaScript可理解的数据结构
$.fn.serializeJson = function() {
        var o = {};
        var a = this.serializeArray();
        $.each(a, function() {
            if (o) {
                if (!o.push) {
                    o = < o >;
                }
                o.push(this.value || '');
            } else {
                o = this.value || '';
            }
        });
        return o;
}
格式: var jsonData = $("#formID").serializeJson();

@ResponseBody改成@RestController

方案一:单纯表单提交

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script type="text/javascript" src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
</head>

<body>
    <form id="login" action="/test04" method="post">
        Email<input type="text" id="inputEmail3" name="email" placeholder="Email">
        Password<input type="password" id="inputPassword3" name="password" placeholder="Password">
        <button type="submit">Sign in</button>
    </form>
</body>

</html>

方案二: ajax提交


<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script type="text/javascript" src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
</head>

<body>
    <form id="login">
        Email<input type="text" id="inputEmail3" name="email" placeholder="Email">
        Password<input type="password" id="inputPassword3" name="password" placeholder="Password">
        <button type="submit" onclick="sign()">Sign in</button>
    </form>

    <script>

        function sign() {
            var loginData = $("#login").serialize()//表单数据
            $.ajax({
                url: "/test04",
                data: loginData,
                type: 'POST',
                contentType: "application/x-www-form-urlencoded",
                success: function (resp) {
                    if (resp == "success") {
                        // window.location.href = "/test.html"//test.html我就不再贴出,就一行helloword
                    }
                }
            })
        }
    </script>
</body>

</html>

@PostMapping改下,如下:

@PostMapping(path = "/test04", consumes = {"multipart/form-data","application/json"})

如有帮助,请采纳,十分感谢!

可以F12看看数据实际提交到后台的形式是表单形式,还是application/json形式

@ResponseBody 这个只能返回数据,不会跳页面

在spring的配置文件中配置


<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="urlMap">
        <map>
            <entry key="/请求的文件路径/**" value="myResourceHandler" />
        </map>
    </property>
    <property name="order" value="100000" />
</bean>
<bean id="myResourceHandler" name="myResourceHandler"
      class="org.springframework.web.servlet.resource.ResourceHttpRequestHandler">
    <property name="locations" value="/请求的文件路径/" />
    <property name="supportedmethods">
        <list>
            <value>get</value>
            <value>head</value>
            <value>post</value>
        </list>
    </property>
</bean>