Java請求Cross跨域配置及Nginx反向代理配置
阿新 • • 發佈:2020-08-10
1.CrossJava跨域配置
首先給出Java的跨域請求cross配置(簡單控制版)
import java.io.IOException; import java.util.Enumeration; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; /** * Cross-Origin Resource Sharing跨源資源共享 過濾器 允許前臺頁面通過ajax或者angualr直接訪問 * */ @Component @Slf4j public class CorsFilter implements Filter { private static final Logger LOGGER = LoggerFactory.getLogger(CorsFilter.class); @Value("${page.home}") private String pageHome; @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletResponse response = (HttpServletResponse)res; HttpServletRequest request = (HttpServletRequest) req; Enumeration<String> headerNames = ((HttpServletRequest) req).getHeaderNames(); while (headerNames.hasMoreElements()){ String s = headerNames.nextElement(); log.info("請求key:{},請求值:{}",s,((HttpServletRequest) req).getHeader(s)); } // 允許的訪問域,允許全部則為*,允許部分則配置詳細的http地址,埠後不能有/ response.setHeader("Access-Control-Allow-Origin", "*"); // 訪問授權有效期 為一週,單位為秒 response.setHeader("Access-Control-Max-Age", "604800"); // 預設只允許GET、POST請求,需要將PUT和DELETE也加入此列 response.setHeader("Access-Control-Allow-Methods", "OPTIONS,GET,POST,PUT,DELETE"); // 允許自定義 header accessToken response.setHeader("Access-Control-Allow-Headers", "Authorization,Origin, Accept, Content-Type, X-HTTP-Method, X-HTTP-METHOD-OVERRIDE,XRequestedWith,X-Requested-With,xhr,custom-enterpriseId,x-clientappversion, x-wxopenid, x-devicetype,accessToken"); response.setHeader("Access-Control-Allow-Credentials", "true"); chain.doFilter(req, res); LOGGER.info("do filter"); } @Override public void destroy() { } }
跨域域名限制版 pagehome用逗號隔開
import java.io.IOException; import java.util.Arrays; import java.util.List; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; /** * Cross-Origin Resource Sharing跨源資源共享 過濾器 允許前臺頁面通過ajax或者angualr直接訪問 * */ @Component public class CorsFilter implements Filter { private static final Logger LOGGER = LoggerFactory.getLogger(CorsFilter.class); public static final String HOST_SPLIT_LINE = ","; public static final String ALLOW_HEADER_SPLIT_LINE = "\\|"; @Value("${page.home}") private String pageHome; @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletResponse response = (HttpServletResponse)res; HttpServletRequest request = (HttpServletRequest)req; List<String> domains = Arrays.asList(pageHome.split(HOST_SPLIT_LINE)); // 獲取發起當前請求的域名 String originHead = request.getHeader("Origin"); int index = index(domains, originHead); if (index >= 0) { String matchHeader = domains.get(index); if (matchHeader.split(ALLOW_HEADER_SPLIT_LINE).length > 1) { String [] headerConfig = matchHeader.split(ALLOW_HEADER_SPLIT_LINE); // 允許的訪問域,允許全部則為*,允許部分則配置詳細的http地址,埠後不能有/ response.setHeader("Access-Control-Allow-Origin", headerConfig[1]); } else { response.setHeader("Access-Control-Allow-Origin", originHead); } } else { response.setHeader("Access-Control-Allow-Origin", domains.get(0)); } // 訪問授權有效期 為一週,單位為秒 response.setHeader("Access-Control-Max-Age", "604800"); // 預設只允許GET、POST請求,需要將PUT和DELETE也加入此列 response.setHeader("Access-Control-Allow-Methods", "OPTIONS,GET,POST,PUT,DELETE"); // 允許自定義 header accessToken response.setHeader("Access-Control-Allow-Headers", "Authorization,Origin, Accept, Content-Type, X-HTTP-Method, X-HTTP-METHOD-OVERRIDE,XRequestedWith,X-Requested-With,xhr,custom-enterpriseId,x-clientappversion, x-wxopenid, x-devicetype,accessToken"); response.setHeader("Access-Control-Allow-Credentials", "true"); chain.doFilter(req, res); LOGGER.debug("do filter"); } @Override public void destroy() { } /** * 計算Header所在索引位置 * @param domains 域名列表 * @param originHeader 當前頁面域名 * @return * @return int 返回型別 * @author caiwenhao * @date 2020年6月30日 上午11:53:31 */ private int index(List<String> domains, String curDomain) { String domain = null; for (int i = 0; i < domains.size(); i++) { domain = domains.get(i); String strs [] = domain.split(ALLOW_HEADER_SPLIT_LINE); if ((null != strs) && (strs[0].equals(curDomain))) { return i; } if (domain.equals(curDomain)) { return i; } } return -1; } }
1.1 幾個注意點
-
.response.setHeader("Access-Control-Allow-Origin", "*"); *可換成具體的域名做精確控制,使用*代表的跨域範圍很大
- .Access-Control-Allow-Headers的引數注意自行檢查,如果需要自定義header中的驗證token欄位必須加上accessToken,否則跨域會失敗
2.Nginx反向代理配置
2.1.首先按正常安裝安裝nginx
2.2.進入/etc/nginx 配置目錄,自行安裝的進入自己的配置目錄
2.3 nginx.cong預設匯入conf.d下的所有檔案
所以我們可將專案的配置放在conf.d下也可自行配置目錄
首先我們給出web端的資源對映路徑,以及其他gzip配置 不需要的可去除
server { #開啟和關閉gzip模式 gzip on; #gizp壓縮起點,檔案大於1k才進行壓縮 gzip_min_length 1k; # gzip 壓縮級別,1-9,數字越大壓縮的越好,也越佔用CPU時間 gzip_comp_level 6; # 進行壓縮的檔案型別。 gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/xml text/javascript application/json image/png image/gif image/jpeg; #nginx對於靜態檔案的處理模組,開啟後會尋找以.gz結尾的檔案,直接返回,不會佔用cpu進行壓縮,如果找不到則不進行壓縮 # gzip_static on|off # 是否在http header中新增Vary: Accept-Encoding,建議開啟 gzip_vary on; # 設定壓縮所需要的緩衝區大小,以4k為單位,如果檔案為7k則申請2*4k的緩衝區 gzip_buffers 4 16k; # 設定gzip壓縮針對的HTTP協議版本 # gzip_http_version 1.1; listen 80; server_name manager.XXX.com; location / {
# web打包資源路徑 root /service/app/XXX/frontEnd/mgmt; try_files $uri $uri/ /index.html?q=$uri&$args; index index.html index.htm; } }
其次我們給出後端appService的介面對映配置,一般將域名也就是ip的80埠對映到我們專案的ip及專案埠(比如我的專案就是部署在本地的4000埠 )
/ 路徑一般配置專案需要的資源路徑,如無也可直接配置反向代理
server { listen 80; server_name api.XXXX.com; location / { root /service/app/hunger_server/master; try_files $uri $uri/ /index.html?q=$uri&$args; index index.html index.htm; } location /hunger { proxy_pass http://127.0.0.1:4000; client_max_body_size 100m; proxy_buffer_size 512k; proxy_buffers 32 32k; proxy_busy_buffers_size 512k; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Accept-Encoding ""; } }