Spring在IE11下抛出Content type不支持异常问题求助
Content type 'text/plain;charset=UTF-8' not supported问题 这问题我之前帮同事排查过类似的,IE11在HTTP请求头的处理逻辑上确实和现代浏览器有不少差异,咱们一步步拆解解决:
一、先从Angular端强制设置正确的请求头
IE11可能会篡改默认的Accept和Content-Type头,导致Spring端识别不到application/json。你可以通过两种方式强制设置:
1. 单个请求显式配置headers
在发起请求时手动指定请求头,确保发送的是application/json:
import { HttpClient, HttpHeaders } from '@angular/common/http'; // 定义全局请求配置 const httpOptions = { headers: new HttpHeaders({ 'Accept': 'application/json', 'Content-Type': 'application/json' }) }; // 发起请求时传入配置 this.http.get('/your-api-endpoint', httpOptions).subscribe(response => { // 处理响应 });
2. 全局拦截器统一配置(推荐)
如果项目中有大量请求,用HttpInterceptor统一给所有请求加上正确的头,避免重复代码:
import { Injectable } from '@angular/core'; import { HttpInterceptor, HttpRequest, HttpHandler } from '@angular/common/http'; @Injectable() export class JsonHeaderInterceptor implements HttpInterceptor { intercept(req: HttpRequest<any>, next: HttpHandler) { // 克隆请求并修改头信息 const modifiedRequest = req.clone({ setHeaders: { 'Accept': 'application/json', 'Content-Type': 'application/json' } }); return next.handle(modifiedRequest); } }
然后在AppModule中注册这个拦截器:
import { HTTP_INTERCEPTORS } from '@angular/common/http'; import { JsonHeaderInterceptor } from './interceptors/json-header.interceptor'; @NgModule({ // ...其他配置 providers: [ { provide: HTTP_INTERCEPTORS, useClass: JsonHeaderInterceptor, multi: true } ] }) export class AppModule { }
二、检查Angular在IE11中的Polyfill支持
Angular6在IE11下需要依赖额外的polyfill才能正常工作,缺失polyfill可能导致HttpClient的行为异常。打开src/polyfills.ts,确保以下polyfill已启用(去掉注释):
// 基础ES6+ polyfill import 'core-js/es6/array'; import 'core-js/es6/date'; import 'core-js/es6/function'; import 'core-js/es6/map'; import 'core-js/es6/object'; import 'core-js/es6/string'; import 'core-js/es7/array'; import 'core-js/es7/object'; // Angular的zone.js import 'zone.js/dist/zone'; // 可选:如果XMLHttpRequest有问题,添加fetch polyfill import 'whatwg-fetch';
如果没有whatwg-fetch,需要先安装:npm install whatwg-fetch --save
三、Spring端做兼容处理
虽然你配置了只支持application/json,但IE11可能发送的Accept头包含text/plain或*/*,导致Spring抛出异常。可以做两种调整:
1. 扩展支持的媒体类型
修改MappingJackson2HttpMessageConverter的配置,添加对text/plain的兼容:
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> <property name="supportedMediaTypes"> <list> <value>application/json</value> <value>text/plain</value> <!-- 兼容IE11的text/plain请求 --> </list> </property> </bean>
2. 优化异常处理器的响应
你的ControllerErrorHandlers目前只记录日志但没有返回有效响应,IE11可能因为收到空响应而出现额外问题。可以修改为返回application/json格式的错误响应:
import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.HttpMediaTypeNotAcceptableException; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; @ControllerAdvice public class ControllerErrorHandlers { private static final Logger LOGGER = LoggerFactory.getLogger(ControllerErrorHandlers.class); @ResponseBody @ExceptionHandler(HttpMediaTypeNotAcceptableException.class) public ResponseEntity<Object> mediaTypeExceptionHandler(HttpMediaTypeNotAcceptableException e) { LOGGER.error("exception: {}", e.getMessage()); // 返回标准JSON格式的错误响应 return ResponseEntity.status(HttpStatus.NOT_ACCEPTABLE) .contentType(MediaType.APPLICATION_JSON) .body("{\"code\": 406, \"message\": \"Unsupported media type, please use application/json\"}"); } }
四、强制IE11使用最新渲染模式
有时候IE11会自动切换到兼容性视图,导致请求行为异常。在页面的<head>中添加meta标签,强制IE使用最新引擎:
<meta http-equiv="X-UA-Compatible" content="IE=edge">
五、排查工具:用IE11开发者工具验证请求头
打开IE11的F12开发者工具,切换到「网络」标签,查看请求的Request Headers,确认Accept和Content-Type是否确实为application/json——这一步能帮你快速定位是Angular发送的问题,还是其他环节的篡改。
内容的提问来源于stack exchange,提问作者nanomader

