添加 DELETE 端点时,资源因 Spring MVC 中的 MIME 类型而被阻止
Resource blocked due to MIME type in Spring MVC when DELETE endpoint added
我正在使用 Spring Boot v2.1.9.RELEASE 和 Thymeleaf 开发网络应用程序。该应用将 server-side 渲染(Spring MVC 常规控制器)与通过 AJAX 调用的其余控制器混合在一起。只要 GET
和 POST
是我使用的唯一 HTTP 方法,该页面就可以正常工作。一旦我添加了一个完全不相关但未使用的 DELETE
REST 控制器,CSS 和 JS 资源就会停止加载,并且浏览器控制台中会显示如下所示的错误:
The resource from “http://localhost:8080/css/demo.css” was blocked due to MIME type (“application/json”) mismatch (X-Content-Type-Options: nosniff)
如果我移除新控制器,页面将再次开始工作。
当我使用网络监视器检查请求时,我观察到:
X-Content-Type-Options: nosniff
header 始终出现在响应中,这与 Spring Security documentation. 一致
- 如果
DELETE
端点不存在,GET /css/demo.css
请求 returns 带有预期的 HTTP 200
代码。 Accept
(请求header)和Content-Type
(响应header)都标记为text/css
。
- 当我添加端点时,上面的请求returns一个
HTTP 405
。 Accept
header 是 text/css
但 Content-Type
变成 application/json
。此外,还添加了一个新的响应 header:Allow: DELETE
.
我的猜测是,当 Spring 扫描控制器并找到 DELETE
方法时,会自动添加一些额外的配置,但我找不到任何参考来证实这一点。我想知道为什么会发生这种情况以及如何避免这种行为。
因为我在本地开发,所以我的 Spring 安全配置非常简单:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public AuthenticationManagerConfigurer authConfigurer() {
return new InMemoryAuthenticationManagerConfigurer();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
authConfigurer().configure(auth);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.formLogin();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
我添加的 REST 控制器几乎什么都不做:
@RestController
public class MotivosController {
private final String CONTROLLER_PATH = "/rest/motivos/{id}";
@RequestMapping(name=CONTROLLER_PATH, method=RequestMethod.DELETE)
public void deleteMotivo(@PathVariable(name="id") String id) {
logger.debug("Eliminando el motivo " + id);
}
// Other members I consider unrelated to the problem go here...
}
CSS和JS文件正在加载到src/main/resources/templates
文件夹下的template.html
文件中,如下:
<link type="text/css" href="/css/demo.css" rel="stylesheet" />
答案比我想象的要容易,我的假设完全错了。我混淆了 @RequestMapping
的 name
属性和 value
属性,因此任何 URL 都匹配该方法。将 name
更改为 value
使其工作。
我正在使用 Spring Boot v2.1.9.RELEASE 和 Thymeleaf 开发网络应用程序。该应用将 server-side 渲染(Spring MVC 常规控制器)与通过 AJAX 调用的其余控制器混合在一起。只要 GET
和 POST
是我使用的唯一 HTTP 方法,该页面就可以正常工作。一旦我添加了一个完全不相关但未使用的 DELETE
REST 控制器,CSS 和 JS 资源就会停止加载,并且浏览器控制台中会显示如下所示的错误:
The resource from “http://localhost:8080/css/demo.css” was blocked due to MIME type (“application/json”) mismatch (X-Content-Type-Options: nosniff)
如果我移除新控制器,页面将再次开始工作。
当我使用网络监视器检查请求时,我观察到:
X-Content-Type-Options: nosniff
header 始终出现在响应中,这与 Spring Security documentation. 一致
- 如果
DELETE
端点不存在,GET /css/demo.css
请求 returns 带有预期的HTTP 200
代码。Accept
(请求header)和Content-Type
(响应header)都标记为text/css
。 - 当我添加端点时,上面的请求returns一个
HTTP 405
。Accept
header 是text/css
但Content-Type
变成application/json
。此外,还添加了一个新的响应 header:Allow: DELETE
.
我的猜测是,当 Spring 扫描控制器并找到 DELETE
方法时,会自动添加一些额外的配置,但我找不到任何参考来证实这一点。我想知道为什么会发生这种情况以及如何避免这种行为。
因为我在本地开发,所以我的 Spring 安全配置非常简单:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public AuthenticationManagerConfigurer authConfigurer() {
return new InMemoryAuthenticationManagerConfigurer();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
authConfigurer().configure(auth);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.formLogin();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
我添加的 REST 控制器几乎什么都不做:
@RestController
public class MotivosController {
private final String CONTROLLER_PATH = "/rest/motivos/{id}";
@RequestMapping(name=CONTROLLER_PATH, method=RequestMethod.DELETE)
public void deleteMotivo(@PathVariable(name="id") String id) {
logger.debug("Eliminando el motivo " + id);
}
// Other members I consider unrelated to the problem go here...
}
CSS和JS文件正在加载到src/main/resources/templates
文件夹下的template.html
文件中,如下:
<link type="text/css" href="/css/demo.css" rel="stylesheet" />
答案比我想象的要容易,我的假设完全错了。我混淆了 @RequestMapping
的 name
属性和 value
属性,因此任何 URL 都匹配该方法。将 name
更改为 value
使其工作。