本文旨在通俗易懂的講解什麼是跨域(CORS),以及如何解決跨域問題。
首先,通過實例解釋一下什麼是跨域:
網絡上的許多頁面都會加載來自不同域的CSS樣式表,圖像和腳本等資源。
出於安全原因,瀏覽器限制從腳本內發起的跨源HTTP請求。因爲瀏覽器採用的是同源策略。是瀏覽器對javaScript施加的安全限制。
什麼是同源呢?就是指的 域名、協議、端口均相同。接下來舉實例闡述
http://www.123.com/index.html 調用 http://www.123.com/server.PHP (非跨域)
http://www.123.com/index.html 調用 http://www.456.com/server.php (主域名不同:123/456,跨域)
http://abc.123.com/index.html 調用 http://def.123.com/server.php(子域名不同:abc/def,跨域)
http://www.123.com:8080/index.html調用 http://www.123.com:8081/server.php(端口不同:8080/8081,跨域)
http://www.123.com/index.html 調用 https://www.123.com/server.php(協議不同:http/https,跨域)
請注意:localhost和127.0.0.1雖然都指向本機,但也屬於跨域。
瀏覽器執行javascript腳本時,會檢查這個腳本屬於哪個頁面,如果不是同源頁面,就不會被執行。
當域名www.abc.com下的js代碼去訪問www.def.com域名下的資源,就會受到限制。
關於跨域(CORS)的闡述到此爲止。
接下來,闡述一下如何解決跨域————註解@CrossOrigin
註解@CrossOrigin使用前提:
JDK1.8+
Spring4.2+
CrossOrigin源碼解析:
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CrossOrigin {
String[] DEFAULT_ORIGINS = { "*" };
String[] DEFAULT_ALLOWED_HEADERS = { "*" };
boolean DEFAULT_ALLOW_CREDENTIALS = true;
long DEFAULT_MAX_AGE = 1800;
/**
* 同origins屬性一樣
*/
@AliasFor("origins")
String[] value() default {};
/**
* 所有支持域的集合,例如"http://domain1.com"。
* <p>這些值都顯示在請求頭中的Access-Control-Allow-Origin
* "*"代表所有域的請求都支持
* <p>如果沒有定義,所有請求的域都支持
* @see #value
*/
@AliasFor("value")
String[] origins() default {};
/**
* 允許請求頭重的header,默認都支持
*/
String[] allowedHeaders() default {};
/**
* 響應頭中允許訪問的header,默認爲空
*/
String[] exposedHeaders() default {};
/**
* 請求支持的方法,例如"{RequestMethod.GET, RequestMethod.POST}"}。
* 默認支持RequestMapping中設置的方法
*/
RequestMethod[] methods() default {};
/**
* 是否允許cookie隨請求發送,使用時必須指定具體的域
*/
String allowCredentials() default "";
/**
* 預請求的結果的有效期,默認30分鐘
*/
long maxAge() default -1;
}
@CrossOrigin使用:
package com.example.demo.controller;
import com.example.demo.domain.User;
import com.example.demo.service.IUserFind;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* @Title: UserController
* @ProjectName demo
* @Description: 請求處理控制器
* @author 淺然
* @date 2018/7/2022:18
**/
@RestController
//實現跨域註解
//origin="*"代表所有域名都可訪問
//maxAge飛行前響應的緩存持續時間的最大年齡,簡單來說就是Cookie的有效期 單位爲秒
//若maxAge是負數,則代表爲臨時Cookie,不會被持久化,Cookie信息保存在瀏覽器內存中,瀏覽器關閉Cookie就消失
@CrossOrigin(origins = "*",maxAge = 3600)
public class UserController {
@Resource
private IUserFind userFind;
@GetMapping("finduser")
public User finduser(@RequestParam(value="id") Integer id){
//此處省略相應代碼
}
}
文章到此爲止,如有不當之處,歡迎各位指正哈。
參考網址: