文章導讀
前言
??跨域問題指的是在Web開發中,由于瀏覽器的同源策略
限制,當一個網頁嘗試訪問與它不同源(協議、域名或端口不同
)的資源時,可能會遇到安全限制導致無法正常訪問的問題。這種策略旨在防止惡意網站讀取或修改其他網站的數據,保護用戶信息安全。
這樣說可能有點抽象,下面具體展開說明。
跨域問題演示
??通常情況下,我們主流的開發模式是:前后端分離。當我們從瀏覽器80訪問服務端81應用
下面我們用一個Web工程,一個后端工程具體簡單演示下。
1、Web工程結構:
-
application.properties
spring.application.name=springboot-cross-web
server.port=8080
-
index.html 頁面
<!DOCTYPE?html>
<html?lang="en">
<head><meta?charset="UTF-8"><meta?http-equiv="X-UA-Compatible"?content="IE=edge"><meta?name="viewport"?content="width=device-width,?initial-scale=1.0"><title>測試跨域請求頁面</title><script?src="js/jquery-3.5.1.min.js"></script>
</head>
<body>
<div><input?type="button"?onclick="crossSubmit()"?value="跨域測試">
</div>
<script>function?crossSubmit()?{//?發送跨域請求jQuery.ajax({url:?"http://localhost:8081/api/cross",type:?"POST",data:?{"key":?"Cross"},success:?function?(result)?{alert("返回數據:"?+?result.data);}});}
</script>
</body>
</html>
2、后端工程結構:
-
application.properties
spring.application.name=springboot-cross
server.port=8081
-
測試應用
@RestController
public?class?CrossAppController?{@RequestMapping("/api/cross")public?HashMap<String,?Object>?crossTest()?{return?new?HashMap<String,?Object>()?{{put("state",?200);put("data",?"success");}};}
}
3、啟動并測試
瀏覽器報錯產生跨域問題。
為什么產生跨域問題?
一般來講,通常產生跨域問題有以下幾種原因:
-
協議不同:如 https和http;
-
端口不同
-
域名不同
這就是常說的同源策略
的問題。產生跨域問題的根源就是請求不同源。
如何解決跨域問題?
從上邊的問題來看,主要在于瀏覽器保護,對參數?"Access-Control-Allow-Origin"
的設置。
主要有下解決方案:
一、使用@CrossOrigin注解
@RestController
@CrossOrigin(origins?=?"*")
public?class?CrossAppController?{@RequestMapping("/api/cross")public?HashMap<String,?Object>?crossTest()?{return?new?HashMap<String,?Object>()?{{put("state",?200);put("data",?"success");}};}
}
演示結果:
二、使用全局跨域配置
@Configuration
public?class?WebConfig?implements?WebMvcConfigurer?{@Overridepublic?void?addCorsMappings(CorsRegistry?registry)?{registry.addMapping("/api/cross").allowedOrigins("*").allowedMethods("GET",?"POST",?"PUT",?"DELETE").allowedHeaders("*");//.allowCredentials(true);}
}
三、使用CorsFilter跨域
@Component
public?class?CorsFilter?implements?Filter?{@Overridepublic?void?doFilter(ServletRequest?req,?ServletResponse?res,?FilterChain?chain)?throws?IOException,?ServletException?{HttpServletResponse?response?=?(HttpServletResponse)?res;HttpServletRequest?request?=?(HttpServletRequest)?req;//?設置允許的來源response.setHeader("Access-Control-Allow-Origin",?"*");//?處理預檢請求if?("OPTIONS".equalsIgnoreCase(request.getMethod()))?{response.setStatus(HttpServletResponse.SC_OK);}?else?{chain.doFilter(req,?res);}}
}
四、使用Nginx來實現跨域
server?{??listen?80;??server_name?your.domain.com;??location?/?{??#?添加CORS相關的響應頭??add_header?'Access-Control-Allow-Origin'?'*';??add_header?'Access-Control-Allow-Methods'?'GET,?POST,?OPTIONS';??add_header?'Access-Control-Allow-Headers'?'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';??#?對于OPTIONS請求,直接返回204狀態碼??if?($request_method?=?'OPTIONS')?{??return?204;??}??#?其他配置...??#?代理到后端服務或其他配置...??#?proxy_pass?http://your_backend/;??#?其他proxy_...指令...??}??
}
總結
-
跨域問題指的是在Web開發中,由于瀏覽器的
同源策略
限制,導致無法正常訪問的問題。 -
主要原理就是請求參數
Access-Control-Allow-Origin