1.web.xml允許跨域名單與允許接口跨域配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<display-name>Archetype Created Web Application</display-name>
......
<!--跨域處理開始 -->
<filter>
<filter-name>cros</filter-name>
<filter-class>com.kuayu.filter.AccessFilter</filter-class>
<init-param>
<param-name>allowDomainRequestUrl</param-name>
<param-value>
/IPermissionService/getVersionSecret.htm,
/IPermissionService/getVersionSecret
</param-value>
</init-param>
<init-param>
<param-name>allowDomain</param-name>
<param-value>
http://ces.bbc.com,
http://ces.bbc.com:80,
https://ces.bbc.com,
https://ces.bbc.com:80
</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>cros</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--跨域處理結束 -->
......
</web-app>
2.跨域過濾器 AccessFilter 類
package com.kuayu.filter;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
@Component
public class AccessFilter extends HttpServlet implements Filter {
private static final long serialVersionUID = 1L;
/** 獲取允許跨域請求的URL */
private Set<String> allowDomainRequestUrls = Collections.emptySet();
/** 獲取允許跨域地址 */
private Set<String> allowDomains = Collections.emptySet();
@Override
public void init(FilterConfig filterConfig) throws ServletException {
String allowDomainRequestUrl = filterConfig.getInitParameter("allowDomainRequestUrl");
String allowDomain = filterConfig.getInitParameter("allowDomain");
//獲取允許跨域請求的URL
allowDomainRequestUrls = strSplitConvertList(allowDomainRequestUrl,",");
//獲取允許跨域地址
allowDomains = strSplitConvertList(allowDomain,",");
}
/**
* String分隔
* @param sourceStr
* @param split
* @return
*/
private Set<String> strSplitConvertList(String sourceStr,String split){
if(StringUtils.isBlank(sourceStr)){
return Collections.emptySet();
}
String[] sourceArray = StringUtils.split(sourceStr,split);
if(null == sourceArray || sourceArray.length == 0){
return Collections.emptySet();
}
Set<String> sets = new HashSet<String>();
for(String str : sourceArray){
if(StringUtils.isNotBlank(str)){
sets.add(str.trim());
}
}
return sets;
}
/**
* 是否包含請求Url
* @param includeURLs
* @param requestUrl
* @return
*/
public static boolean isIncludeUrl(Set<String> includeURLs, String requestUrl){
if(CollectionUtils.isEmpty(includeURLs)){
return Boolean.FALSE;
}
for(String includeURL : includeURLs){
if(requestUrl.endsWith(includeURL)){
return Boolean.TRUE;
}
}
return Boolean.FALSE;
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
String requestUrl = httpRequest.getServletPath();
//獲取請求的域名
String originHeader= httpRequest.getHeader("Origin");
//如果請求的域爲允許跨域的域名 且 請求URL爲允許跨域的URL
if (allowDomains.contains(originHeader) && isIncludeUrl(allowDomainRequestUrls,requestUrl)){
httpResponse.setHeader("Access-Control-Allow-Origin", originHeader);
httpResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
httpResponse.setHeader("Access-Control-Max-Age", "3600");
//表明服務器支持的所有頭信息字段
httpResponse.setHeader("Access-Control-Allow-Headers","Origin,No-Cache,X-Requested-With,If-Modified-Since,Pragma,Last-Modified,Cache-Control,Expires,Content-Type,X-E4M-With,userId,token,X-Test-TOKEN");
//如果要把Cookie發到服務器,需要指定Access-Control-Allow-Credentials字段爲true;
httpResponse.setHeader("Access-Control-Allow-Credentials", "true");
httpResponse.setHeader("XDomainRequestAllowed","1");
/* Cookie[] cookies = httpRequest.getCookies();
// 然後迭代之
String token = "USER_ID";
if (cookies != null && cookies.length > 0) { //如果沒有設置過Cookie會返回null
for (Cookie cookie : cookies) {
if(cookie.getName().equals("token")){
token = cookie.getValue();
}
}
}
Cookie cookie = new Cookie("token",token);
cookie.setPath("/");
httpResponse.addCookie(cookie);*/
}
chain.doFilter(request, httpResponse);
}
}
3.常見問題
a.針對特定接口跨域時,跨域邏輯需要放入過濾類中來實現,請求方式Object在到接口之前已被攔截了。
b.請求未跨域時, String originHeader= httpRequest.getHeader("Origin");獲取內容爲空對象。