You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot POST请求出现415 Unsupported Media Type错误排查

POST接口415错误排查

我开发了一个POST接口用于将form.html的数据存入数据库,Postman请求能正常返回200且数据保存成功,但在Chrome、Opera、Edge浏览器中点击“Continue”按钮后会出现415错误;Chrome DevTools显示请求返回200并跳转,但浏览器仍显示415错误。

前端JavaScript代码

function sendData() {
  const form = document.getElementById('form');
  const insuranceSelect = form.querySelector('#insurance');
  const selectedInsurance = insuranceSelect.options[insuranceSelect.selectedIndex].value;

  const data = {
    "firstName": form.querySelector('#firstName').value,
    "lastName": form.querySelector('#lastName').value,
    "email": form.querySelector('#email').value,
    "password": form.querySelector('#password').value,
    "birthDate": form.querySelector('#birthDate').value, // ISO 8601 format
    "birthNumber": form.querySelector('#birthNumber').value,
    "phoneNumber": form.querySelector('#phoneNumber').value,
    "insuranceCompany": selectedInsurance
  };


  fetch('/Insurance/register', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Accept': 'application/json',
      'Origin': 'http://localhost:8080'
    },
    body: JSON.stringify(data)
  })
    .then(response => {
      console.log('Response status code:', response.status);

      if (!response.ok) {
        throw new Error(`Registration failed with status: ${response.status}`);
      }

      console.log('Registration successful!');
      window.location.href = "/Insurance/login";

    })
    .catch(error => {
      console.error('Error during registration:', error.message);
    });
}

后端Java接口代码

@PostMapping(value = "/register", consumes = {"application/json"},produces = {"application/json"})
public ResponseEntity<?> registerUser(@RequestBody  RegistrationForm registrationForm) {

    System.out.println(registrationForm.toString());

    Client client = clientService.createClient(registrationForm);

    ClientDAO dao = new ClientDAO(sessionFactory);
    if (validateClient(client)) {
        if (dao.saveClient(client)) {

            return ResponseEntity.ok().body("Registration was successful!");

        } else {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Failed to save the client.");
        }
    } else {
        return ResponseEntity.badRequest().body("Please provide all necessary information to complete registration");
    }
}

相关日志

2024-01-14T21:53:04.249+01:00 DEBUG 13352 --- [nio-8080-exec-8] o.s.j.d.DriverManagerDataSource          : Creating new JDBC DriverManager Connection to [jdbc:postgresql://localhost:5432/insuranceDatabase]
2024-01-14T21:53:04.270+01:00 DEBUG 13352 --- [nio-8080-exec-7] o.s.web.servlet.DispatcherServlet        : POST "/Insurance/register", parameters={masked}
2024-01-14T21:53:04.277+01:00  WARN 13352 --- [nio-8080-exec-7] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content-Type 'application/x-www-form-urlencoded' is not supported]
2024-01-14T21:53:04.278+01:00 DEBUG 13352 --- [nio-8080-exec-7] o.s.web.servlet.DispatcherServlet        : Completed 415 UNSUPPORTED_MEDIA_TYPE
2024-01-14T21:53:04.281+01:00 DEBUG 13352 --- [nio-8080-exec-7] o.s.web.servlet.DispatcherServlet        : "ERROR" dispatch for POST "/Insurance/error", parameters={masked}
2024-01-14T21:53:04.285+01:00 DEBUG 13352 --- [nio-8080-exec-7] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#errorHtml(HttpServletRequest, HttpServletResponse)
2024-01-14T21:53:04.286+01:00 DEBUG 13352 --- [nio-8080-exec-7] o.j.s.OpenEntityManagerInViewInterceptor : Opening JPA EntityManager in OpenEntityManagerInViewInterceptor
2024-01-14T21:53:04.294+01:00 DEBUG 13352 --- [nio-8080-exec-7] o.s.w.s.v.ContentNegotiatingViewResolver : Selected 'text/html' given [text/html, text/html;q=0.8]
2024-01-14T21:53:04.295+01:00 DEBUG 13352 --- [nio-8080-exec-7] o.j.s.OpenEntityManagerInViewInterceptor : Closing JPA EntityManager in OpenEntityManagerInViewInterceptor
2024-01-14T21:53:04.295+01:00 DEBUG 13352 --- [nio-8080-exec-7] o.s.web.servlet.DispatcherServlet        : Exiting from "ERROR" dispatch, status 415
2024-01-14T21:53:04.475+01:00 DEBUG 13352 --- [nio-8080-exec-8] o.s.w.s.m.m.a.HttpEntityMethodProcessor  : Using 'application/json', given [application/json] and supported [application/json]
2024-01-14T21:53:04.477+01:00 DEBUG 13352 --- [nio-8080-exec-8] o.s.w.s.m.m.a.HttpEntityMethodProcessor  : Writing ["Registration was successful!"]
2024-01-14T21:53:04.479+01:00 DEBUG 13352 --- [nio-8080-exec-8] o.j.s.OpenEntityManagerInViewInterceptor : Closing JPA EntityManager in OpenEntityManagerInViewInterceptor
2024-01-14T21:53:04.480+01:00 DEBUG 13352 --- [nio-8080-exec-8] o.s.web.servlet.DispatcherServlet        : Completed 200 OK

问题原因及解决方案

从日志能清楚看到,/Insurance/register收到了两次请求:

  1. 第一次是application/x-www-form-urlencoded格式,被接口拒绝返回415;
  2. 第二次是正确的application/json格式,处理成功返回200。

这说明浏览器同时触发了两次提交:一次是form的默认提交行为(自动用x-www-form-urlencoded格式发请求),另一次是你写的fetch AJAX请求。浏览器显示的415错误来自第一次无效请求。

解决方法:阻止form默认提交

修改sendData函数,添加阻止默认行为的代码:

function sendData(event) {
  // 阻止form的默认提交逻辑
  event.preventDefault();
  
  // 原有的数据收集和fetch请求代码...
}

同时确保表单按钮的事件绑定传递event参数,或者直接在form的onsubmit事件中处理:

<form id="form" onsubmit="sendData(event); return false;">
  <!-- 表单内容 -->
  <button type="submit">Continue</button>
</form>

这样就能只保留fetch的AJAX请求,415错误会消失。

内容的提问来源于stack exchange,提问作者Martin Hároník

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 00:40:55