1.前言
以前做項目 ,基本上是使用 MVC 模式 ,使得視圖與模型綁定 ,前后端地址與端口都一樣 ,
但是現在有些需求 ,需要暴露給外網訪問 ,那么這就出現了個跨域問題 ,與同源原則沖突,
造成訪問失敗 ,於是出了個CORS策略 ,
引用官方解釋:
CORS是一個W3C標准,全稱是"跨域資源共享"(Cross-origin resource sharing)。
它允許瀏覽器向跨源服務器,發出ajax請求,從而克服了AJAX只能 同源使用的限制。
CORS依賴於服務器端的設定,只要在服務器端進行了設置,就可以實現相應的資源訪問。
它允許瀏覽器向跨源服務器,發出ajax請求,從而克服了AJAX只能 同源使用的限制。
CORS依賴於服務器端的設定,只要在服務器端進行了設置,就可以實現相應的資源訪問。
網上找了很多解決方式,有后端方案、有<link>標簽方案等,質量參差不齊,甚至直接是轉載連測試都不做 ,一時半會讓我費解好久。。。
2.跨域失敗根本原因
其實所謂的跨域問題 ,僅僅是局限於 前端頁面 【腳本或表單】 訪問了與該前端 主機地址【包括ip和端口】 不一樣的 遠程后端接口 ,其實該前端的請求是成功發送到了遠程后端 ,
但是因為請求頭信息原因 ,遠程后端檢查出 請求來源的前端頁面的主機地址【包括ip和端口】 不是自己的本地 的地址, 因此拒絕了該請求 。
因此 ,跨域問題的關鍵不是前端設置,而是后端設置 ,前端不需要改動 。
【后端與后端地址不同是可以相互訪問的 ,不存在跨域問題,不然 做 spring cloud 分布式微服務框架豈不是被煩死?== 】
3.解決操作 【適用於spring boot 與 spring MVC】
我准備了兩個工程 ,端口5601負責前端 ,端口8001 負責后端
(1)看一下前端源碼 , 前端5601 向端口8001 發送請求,如果直接 發送請求,必然報錯

<!DOCTYPE html> <html lang="zh" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3"> <head> <meta charset="UTF-8"> <title>index</title> </head> <body> 你好 ,世界 ,2333 <!--<p>點擊 去home.html頁面</p>--> <hr> <label> 發送的內容: <input id="text" type="text"> </label> <button onclick="dosome()">點我,發送信息</button> <hr> 返回的結果:<span id="res"></span> <!--<link href="/js/jquery-1.11.1.min.js" rel="stylesheet"/>--> <!--當前路徑是/html/** ,因此需要返回一級 ,所以用 ../js/ --> <script src="../js/jquery-1.11.1.min.js" ></script> <script> function dosome() { let text = $("#text").val(); if (text.trim() == "") { alert("不能為空"); return; } //URL是URI的子集,所有的URL都是URI,但不是每個URI都是URL,還有可能是URN。 let url = "http://localhost:8001/getname"; $.ajax({ async: true, type: 'post', data: {"name": text}, //這里類型是json,那么跨域的后端需要是map類型、po實體類等 json類型 才能接收數據 dataType: "json", url: url, success: function (data) { console.log(data); //請求成功回調函數 if (data != null) { // alert("有數據返回") $("#res").html(JSON.stringify(data)) } else { alert("系統異常") } } }); } </script> </body> </html>
(2)后端該怎么寫呢?
其實很簡單
如果是spring boot ,直接使用 注解@CrossOrigin即可
如果是 springMVC 則使用 設置響應頭 即可 ,當然,spring boot 也是兼容這個方法的
源碼
【如果項目設置了spring security ,需要其他配置,在我的其他隨筆有詳細記載】
但是
注意:返回的數據需要與前端對應,否則前端無法獲取返回結果
什么意思呢?
比如前端設置的返回數據類型是 json
那么后端要么返回jsonp,要么返回 Map 、List<Map>、po實體類, 不然前端無法識別數據,
比如返回String類型會造成 前端json類型解析不出來
4.測試
啟動項目
端口5601 ,訪問網址 http://localhost:5601/html/index.html
輸入文字 ,點擊發送 ,向端口8001 發送請求 ,希望得到處理結果
成功。。。撒花 !!!