跨域的原理及解決方案

跨域限制訪問,即爲瀏覽器禁止訪問其他網站的資源,是瀏覽器的限制。如果缺少了同源策略,網頁很容易受到XSS、CSFR等攻擊。

同源策略是Web應用程序安全性模型中的重要概念。根據該策略,Web瀏覽器允許第一個網頁中包含的腳本訪問第二個網頁中的數據,但前提是兩個網頁具有相同的來源。來源由URI,主機名(hostname) 和端口號(port) 的組合定義。此策略可防止一個頁面上的惡意腳本通過該頁面的DOM(Document Object Model)獲得對另一網頁上敏感數據的訪問。

跨域場景

當一個請求 URL 的協議域名端口三者之間任意一個與當前頁面 URL 不同即爲跨域

當前頁面URL 請求頁面URL 是否跨域 原因
http://www.test.com/ http://www.test.com/index.html 同源(協議、域名、端口號相同)
http://www.test.com/ https://www.test.com/index.html 協議不同(http/https)
http://www.test.com/ http://www.baidu.com/ 主域名不同(test/baidu)
http://www.test.com/ http://blog.test.com/ 子域名不同(www/blog)
http://www.test.com:8080/ http://www.test.com:8081/ 端口號不同

跨域解決方案

JSONP

由於同源策略,一般來說網頁無法跨域請求資源,而 HTML 的 <script>元素是一個例外。利用 <script>元素的這個開放策略,網頁可以得到從其他來源動態產生的JSON數據,而這種使用模式就是所謂的 JSONP。用JSONP抓到的數據並不是JSON,而是任意的JavaScript,用 JavaScript 解釋器運行而不是用 JSON 解析器解析。

JSONP優點是簡單兼容性好,可用於解決主流瀏覽器的跨域數據訪問的問題。缺點是僅支持 get 方法,具有侷限性;且可能會遭受 XSS 攻擊。

CORS

CORS 是跨域資源分享(Cross-Origin Resource Sharing)的縮寫。它是 W3C 標準,屬於跨源 AJAX 請求的根本解決方法。

  • Access-Control-Allow-Origin 設置允許請求的域名,多個域名以逗號分隔
  • Access-Control-Allow-Methods 設置允許請求的方法,多個方法以逗號分隔
  • Access-Control-Allow-Headers 設置允許請求自定義的請求頭字段,多個字段以逗號分隔
  • Access-Control-Allow-Credentials 設置是否允許發送 Cookies

常用的跨域配置只需設置 Access-Control-Allow-Origin,推薦設置爲對應域名。但當使用 Cookies 時,還需要配置Access-Control-Allow-Credentialstrue,且此時Access-Control-Allow-Origin 的配置不能爲*,而必須配置爲具體的域名。

Java 跨域實現方案

JSONP

Spring 4 ~ Spring 5 低版本中支持全局Jsonp。在 Spring 5 高版本中棄用,且標註建議使用@CrossOrigin

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.AbstractJsonpResponseBodyAdvice;

/**
*
* 統一支持 jsonp 的配置輸出
* 使用說明:@RequestMapping 中指定 produces 爲 application/json;charset=UTF-8 即可
* 例子:@RequestMapping(path = "/signin", produces = "application/json;charset=UTF-8")
*
*/
@ControllerAdvice(basePackages = {"com.yy.ent.union.zone.controller"})
public class JsonpAdvice extends AbstractJsonpResponseBodyAdvice {
	public JsonpAdvice() {
		super("callback", "jsonpcb");
	}
}

@CrossOrigin

使用@CrossOrigin註解時,推薦指定域名,避免使用*的默認配置,產生不安全的隱患

@RestController
@CrossOrigin(origins = "*")
public class TestController {}

當需要使用Cookies時,要配置allowCredentials參數,使用時必須指定具體的域

@CrossOrigin(origins = "http://www.test.com/", allowCredentials = "true")

參考資料:
1.什麼是跨域?跨域解決方法

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章