Ajax (Asynchronous JavaScript and XML) 是一种在不重新加载整个页面的情况下与服务器交换数据并更新部分网页的技术。Spring MVC 是 Spring 框架中的一个模块,用于构建 Web 应用程序。
原因:浏览器安全策略限制跨域请求。
解决方案:
@RestController
@RequestMapping("/api")
public class MyController {
@CrossOrigin // 在控制器方法上添加此注解
@GetMapping("/data")
public ResponseEntity<String> getData() {
return ResponseEntity.ok("Success");
}
}
或者在Spring Boot配置类中添加全局CORS配置:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "POST", "PUT", "DELETE");
}
}
原因:前端发送的请求类型与后端控制器方法不匹配。
解决方案: 确保前后端请求类型一致:
前端Ajax示例:
$.ajax({
url: '/api/data',
type: 'POST', // 必须与后端@RequestMapping或@PostMapping匹配
data: JSON.stringify({name: 'test'}),
contentType: 'application/json',
success: function(response) {
console.log(response);
}
});
后端控制器:
@PostMapping("/data")
public ResponseEntity<String> handleData(@RequestBody MyData data) {
// 处理逻辑
return ResponseEntity.ok("Processed");
}
原因:前端发送的数据格式与后端期望的不一致。
解决方案: 确保数据格式正确:
前端:
$.ajax({
url: '/api/data',
type: 'POST',
data: JSON.stringify({key: 'value'}), // 确保转换为JSON字符串
contentType: 'application/json', // 设置正确的Content-Type
// ...
});
后端:
@PostMapping("/data")
public ResponseEntity<String> handleData(@RequestBody Map<String, String> data) {
// 使用@RequestBody接收JSON数据
String value = data.get("key");
return ResponseEntity.ok(value);
}
原因:Spring Security默认启用CSRF保护。
解决方案: 前端发送CSRF令牌:
var token = $("meta[name='_csrf']").attr("content");
var header = $("meta[name='_csrf_header']").attr("content");
$.ajax({
url: '/api/data',
type: 'POST',
beforeSend: function(xhr) {
xhr.setRequestHeader(header, token);
},
// ...
});
或者在后端配置中禁用CSRF(不推荐生产环境):
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
}
}
原因:前端发送的参数与后端方法参数不匹配。
解决方案: 确保参数名称一致:
前端:
$.ajax({
url: '/api/data?id=123&name=test', // 查询参数
type: 'GET',
// ...
});
后端:
@GetMapping("/data")
public ResponseEntity<String> getData(
@RequestParam("id") Long id,
@RequestParam("name") String name) {
// 处理逻辑
return ResponseEntity.ok("Success");
}
原因:请求路径与控制器映射路径不匹配。
解决方案: 检查路径是否正确:
前端:
$.ajax({
url: '/api/data', // 确保与后端@RequestMapping一致
// ...
});
后端:
@RestController
@RequestMapping("/api") // 确保路径匹配
public class MyController {
@GetMapping("/data") // 组合路径为/api/data
public ResponseEntity<String> getData() {
return ResponseEntity.ok("Success");
}
}
原因:Content-Type不匹配。
解决方案: 确保前后端Content-Type一致:
前端:
$.ajax({
url: '/api/data',
type: 'POST',
data: JSON.stringify({key: 'value'}),
contentType: 'application/json', // 明确指定Content-Type
// ...
});
后端:
@PostMapping(value = "/data", consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<String> handleJson(@RequestBody MyData data) {
// 处理逻辑
return ResponseEntity.ok("Processed");
}
通过以上分析和解决方案,应该能够解决大多数Ajax调用Spring MVC控制器时的错误请求问题。