在過濾器里面添加頭就可以了蘑拯,但是會碰到下面的問題:
. A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is true. Origin 'http://localhost' is therefore not allowed access. The credentials mode of an XMLHttpRequest is controlled by the withCredentials attribute.
當前端請求有參數(shù):
withCredentials: true的時候會出現(xiàn)上述問題贺辰,因為瀏覽器的安全策略,當允許 credentials 的時候晦攒,Access-Control-Allow-Origin 值不能是*
,而必須是一個指定的域名, 那么如何針對不同的訪問設(shè)定對應的跨源允許域呢啃沪?
HTTP 中的Referer能很好地實現(xiàn)該需求昧廷,當在一個域下發(fā)起一個 CORS 請求時钧敞,HTTP 請求頭的 Referer 值會自動被設(shè)置為當前頁面域,此時只要在服務器端讀取 Referer 值麸粮,構(gòu)造出相應的 Access-Control-Allow-Origin 值即可溉苛,參考下面代碼
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
String referer = req.getHeader("referer");
HttpServletResponse res = (HttpServletResponse) response;
if (!StringUtils.isEmpty(referer)) {
try {
res.setHeader("Access-Control-Allow-Origin", getHost(referer));
} catch (Exception e) {
log.error(e.getMessage(), e);
res.setHeader("Access-Control-Allow-Origin", "*");
}
} else {
res.setHeader("Access-Control-Allow-Origin", "*");
}
res.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
res.setHeader("Access-Control-Max-Age", "3600");
res.setHeader("Access-Control-Allow-Headers", "Content-Type, token, nonce, signature, uid");
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
// 防止流讀取一次后就沒有了, 所以需要將流繼續(xù)寫出去
ServletRequest requestWrapper = new BodyReaderHttpServletRequestWrapper(httpServletRequest);
chain.doFilter(requestWrapper, response);
}
private String getHost(String referer) {
String split = "/";
String[] ss = referer.split(split);
return ss[0] + split + ss[1] + split + ss[2];
}