跨域問題產生、原理、解決方案
文章導讀
前言
跨域問題指的是在Web開發中,由於瀏覽器的
同源策略
限制,當一個網頁嘗試存取與它不同源(
協定、網域名稱或埠不同
)的資源時,可能會遇到安全限制導致無法正常存取的問題。這種策略旨在防止惡意網站讀取或修改其他網站的數據,保護使用者資訊保安。
這樣說可能有點抽象,下面具體展開說明。
跨域問題演示
通常情況下,我們主流的開發模式是:前後端分離。當我們從瀏覽器80存取伺服端81套用
下面我們用一個Web工程,一個後端工程具體簡單演示下。
1、Web工程結構:
application.properties
spring.application.name=springboot-cross-web
server.port=8080
index.html 頁面
<!DOCTYPE html>
<htmllang="en">
<head>
<metacharset="UTF-8">
<metahttp-equiv="X-UA-Compatible"content="IE=edge">
<metaname="viewport"content="width=device-width, initial-scale=1.0">
<title>測試跨域請求頁面</title>
<scriptsrc="js/jquery-3.5.1.min.js"></script>
</head>
<body>
<div>
<inputtype="button"onclick="crossSubmit()"value="跨域測試">
</div>
<script>
functioncrossSubmit() {
// 發送跨域請求
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 classCrossAppController{
@RequestMapping("/api/cross")
public HashMap<String, Object> crossTest(){
returnnew HashMap<String, Object>() {{
put("state", 200);
put("data", "success");
}};
}
}
3、啟動並測試
瀏覽器報錯產生跨域問題。
為什麽產生跨域問題?
一般來講,通常產生跨域問題有以下幾種原因:
協定不同:如 https和http;
埠不同
網域名稱不同
這就是常說的
同源策略
的問題。產生跨域問題的根源就是請求不同源。
如何解決跨域問題?
從上邊的問題來看,主要在於瀏覽器保護,對參數
"Access-Control-Allow-Origin"
的設定。
主要有下解決方案:
一、使用@CrossOrigin註解
@RestController
@CrossOrigin(origins = "*")
public classCrossAppController{
@RequestMapping("/api/cross")
public HashMap<String, Object> crossTest(){
returnnew HashMap<String, Object>() {{
put("state", 200);
put("data", "success");
}};
}
}
演示結果:
二、使用全域跨域配置
@Configuration
public classWebConfigimplementsWebMvcConfigurer{
@Override
publicvoidaddCorsMappings(CorsRegistry registry){
registry.addMapping("/api/cross")
.allowedOrigins("*")
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowedHeaders("*");
//.allowCredentials(true);
}
}
三、使用CorsFilter跨域
@Component
public classCorsFilterimplementsFilter{
@Override
publicvoiddoFilter(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
👇🏻 點選下方閱讀原文,獲取魚皮往期編程幹貨。
往期推薦