Spring boot处理OPTIONS请求
一、现象
从fetch说起,用fetch构造一个POST请求。
1 fetch('http://127.0.0.1:8000/api/login', { 2 method: "POST", 3 headers: ({ 4 'Content-Type': 'application/x-www-form-urlencoded' 5 }), 6 body: "name=" + name + "&password=" + pwd 7 }).then((res) = >{ 8 console.log(res.status); 9 return res.json() 10 }).then((data) = >{ 11 // console.log(data.result) 12 let loginResult = data.result 13 if (loginResult == 'ok') { 14 dispatch(getSuccess(data.list)) browserHistory.push('/index') 15 } else { 16 console.log("illegal login in !") 17 } 18 }). 19 catch((e) = >{ 20 console.log(e.message) 21 })
调用的API服务是Spring boot开发的。
这个POST发出去,一切正常。
由于业务需要,我增加一个头字段:Authorization。
fetch请求的代码修改如下:
1 ... 2 3 headers: ({ 4 'Content-Type': 'application/x-www-form-urlencoded', 5 'Authorization': '1111111222' 6 }), 7 body: "name=" + name + "&password=" + pwd 8 }).then((res) = >{ 9 10 ...
问题出现了,服务器收到一个OPTIONS请求?!
二、原因
这是fetch出于安全性考虑做的一次服务器预查询,而我的服务没有做相应的处理,所以业务处理失败了。
三、解决
方法一:
网上查到的最多的说法就是:
在application.properties文件中增加这一行配置:
spring.mvc.dispatch-options-request=true
遗憾的是,我的环境配置没有生效。
方法二:
手动写一个Filter:
0 @Component
1 public class CorsFilter implements Filter { 2 @Override 3 public void init(FilterConfig filterConfig) throws ServletException { 4 // TODO Auto-generated method stub 5 } 6 7 @Override 8 public void doFilter(ServletRequest req, ServletResponse res, 9 FilterChain chain) throws IOException, ServletException { 10 HttpServletResponse response = (HttpServletResponse) res; 11 response.setHeader("Access-Control-Allow-Origin", "*"); 12 response.setHeader("Access-Control-Allow-Methods", 13 "POST, GET, OPTIONS, DELETE"); 14 response.setHeader("Access-Control-Max-Age", "3600"); 15 response.setHeader("Access-Control-Allow-Headers", 16 "Content-Type, x-requested-with, X-Custom-Header, Authorization"); 17 chain.doFilter(req, res); 18 } 19 20 @Override 21 public void destroy() { 22 // TODO Auto-generated method stub 23 } 24 }
一点说明:
response.setHeader("Access-Control-Allow-Headers", "Content-Type, x-requested-with, X-Custom-Header, Authorization");
配置中的Authorization是和请求中自定义的头部字段是一样的。
通过这个过滤器,fetch后续的POST请求就可以顺利的发出了。
上善若水,水利万物而不争。