在過濾器里面添加頭就可以了,但是會碰到下面的問題:
. 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.
當前端請求有參數:
withCredentials: true的時候會出現上述問題,因為瀏覽器的安全策略,當允許 credentials 的時候,Access-Control-Allow-Origin 值不能是*
,而必須是一個指定的域名, 那么如何針對不同的訪問設定對應的跨源允許域呢?
HTTP 中的Referer能很好地實現該需求,當在一個域下發起一個 CORS 請求時,HTTP 請求頭的 Referer 值會自動被設置為當前頁面域,此時只要在服務器端讀取 Referer 值,構造出相應的 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;
// 防止流讀取一次后就沒有了, 所以需要將流繼續寫出去
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];
}