Java 跨域問題的處理方式
問題
在頁面上要使用 Ajax 請求去獲取另外一個服務的數據,由于瀏覽器的 同源策略,所以直接請求會得到一個 Error。
Failed to load https://www.baidu.com/: No ’Access-Control-Allow-Origin’ header is present on the requested resource. Origin ’http://localhost:3000’ is therefore not allowed access. If an opaque response serves your needs, set the request’s mode to ’no-cors’ to fetch the resource with CORS disabled.
大概就是這樣的一個錯誤,關鍵詞是 Access-Control-Allow-Origin,一般出現這個都是跨域問題。
解決方案
解決跨域問題的方式有很多,但這里之說 Cors 的方案。
在后臺添加一個 Filter 過濾器
/** * 使用自定義的 Filter 攔截器實現跨域請求、 * 適用于所有的 Java Web 項目并且不局限于某個框架 * 注:此處的 @Component 僅為讓 Spring 知道這個 Bean, 不然攔截器不會加載 * * @author rxliuli */public class CustomCorsFilterConfig implements Filter { @Override public void init(FilterConfig filterConfig) { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { //允許所有來源 String allowOrigin = '*'; //允許以下請求方法 String allowMethods = 'GET,POST,PUT,DELETE,OPTIONS'; //允許以下請求頭 String allowHeaders = 'Content-Type,X-Token,Authorization'; //允許有認證信息(cookie) String allowCredentials = 'true'; String origin = request.getHeader('Origin'); //此處是為了兼容需要認證信息(cookie)的時候不能設置為 * 的問題 response.setHeader('Access-Control-Allow-Origin', origin == null ? allowOrigin : origin); response.setHeader('Access-Control-Allow-Methods', allowMethods); response.setHeader('Access-Control-Allow-Credentials', allowCredentials); response.setHeader('Access-Control-Allow-Headers', allowHeaders); //處理 OPTIONS 的請求 if ('OPTIONS'.equals(request.getMethod())) { response.setStatus(HttpServletResponse.SC_OK); return; } filterChain.doFilter(request, response); } @Override public void destroy() { }}
在 web.xml 文件中添加攔截器配置(注:如果可能就配置成第一個 Filter)
<!--cors 跨域訪問--><filter> <filter-name>customCorsFilterConfig</filter-name> <filter-class>CustomCorsFilterConfig</filter-class></filter><filter-mapping> <filter-name>customCorsFilterConfig</filter-name> <url-pattern>/*</url-pattern></filter-mapping>
Spring Web 的解決方案
配置一個每次請求都過濾一次的 Filter 就好了
@Configurationpublic class CorsConfig { @Bean public OncePerRequestFilter corsFilter() { return new OncePerRequestFilter() { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {//允許所有來源String allowOrigin = '*';//允許以下請求方法String allowMethods = 'GET,POST,PUT,DELETE,OPTIONS';//允許以下請求頭String allowHeaders = 'Content-Type,X-Token,Authorization';//允許有認證信息(cookie)String allowCredentials = 'true';String origin = request.getHeader('Origin');//此處是為了兼容需要認證信息(cookie)的時候不能設置為 * 的問題response.setHeader('Access-Control-Allow-Origin', origin == null ? allowOrigin : origin);response.setHeader('Access-Control-Allow-Methods', allowMethods);response.setHeader('Access-Control-Allow-Credentials', allowCredentials);response.setHeader('Access-Control-Allow-Headers', allowHeaders);//處理 OPTIONS 的請求if ('OPTIONS'.equals(request.getMethod())) { response.setStatus(HttpServletResponse.SC_OK); return;}filterChain.doFilter(request, response); } }; }}
使用示例
下面是一些簡單的使用 fetch 進行跨域請求的示例:
簡單 fetch 請求,和正常使用 fetch 并無區別fetch(url) .then(res => res.json()) .then(json => console.log(json)) 表單請求
var fd = new FormData()fd.append(’username’, ’rx’)fd.append(’password’, ’rx’)fetch(url, { method: ’POST’, body: fd,}) .then(res => res.json()) .then(json => console.log(json)) 需要認證的請求
fetch(url, { /** * 關鍵就在這里,代表用戶是否應該在跨域的情況下發送 cookies 和 HTTP Basic authentication 等驗信息以及服務端能否返回 Set-Cookie(服務端 Session 需要使用這個向 cookie 中設置 sessionId)。 * 包含三個可選值:omit(從不發送), same-origin(同源才發送), include(總會發送) * 參考鏈接:<https://developer.mozilla.org/zh-CN/docs/Web/API/Request/credentials> */ credentials: ’include’,}) .then(res => res.json()) .then(json => console.log(json))
注:如果想要服務端返回 Set-Cookie(SessionId 也需要通過這個響應屬性去設置) 就必須設置這個請求參數!
那么,之后在前端跨域請求的時候就可以愉快地玩耍啦(v^_^)v
以上就是Java 跨域問題的處理方式的詳細內容,更多關于Java 跨域的資料請關注好吧啦網其它相關文章!
相關文章: