跨域問題
跨域問題是指浏覽器在執行JavaScript代碼的時候,由于浏覽器同源政策的限制,隻能通路同源的資源,不能跨域通路。
解決跨域問題的兩種方式:
- jsonp(JSON with Padding)是json的一種使用模式,前端解決跨域問題的方法,隻支援GET請求,需要後端提供jsonp接口
- CORS(Cross-Origin Resource Sharding)跨域資源共享,後端解決跨域問題的方法
jsonp
原理:
本質就是利用<script>标簽的src屬性不受同源政策限制,請求跨域的資料接口,并通過函數調用的形式,接收跨域接口響應回來的資料。
- 後端接口示例:
接口傳回拼接的函數字元串,函數字元串的參數,就是傳回給前端的資料。
- 一個簡單的jsonp請求:
<body>
<script>
function success(data) {
console.log('JSONP響應回來的資料');
console.log(data);
}
</script>
//這裡傳回的是一個函數調用
<script src="http://www.example.com/api/jsonp?callback=success¶m1=xx¶m2=xxx">
</script>
</body>
- ajax方式jsonp請求:
$.ajax({
url: 'http://www.example.com/api/jsonp?param1=xx¶m2=xxx',
dataType: 'jsonp',
success: function(data) {
console.log(data);
}
})
// 或
$.ajax({
url: 'http://www.example.com/api/jsonp?param1=xx¶m2=xxx',
dataType: 'jsonp',
// 發送到服務端的參數名稱,預設值為 callback
jsonp: 'callback',
// 自定義的回調函數名稱,預設jquery自動生成,如果指定了jsonpCallback,就可以在ajax外做傳回值處理,不然隻能在success回調函數中處理傳回值
jsonpCallback: 'successCallback'
})
function successCallback(data) {
console.log(data);
}
CORS
原理:
在http響應頭中設定允許跨域通路的特定字段,如 Access-Control-Allow-Origin 、 Access-Control-Allow-Methods 、 Access-Control-Allow-Headers 等。
三種實作代碼示例(這裡代碼基于springboot):
- 使用CorsFilter實作跨域通路:
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
// config.addAllowedOrigin("https://www.example1.com");
// config.addAllowedOriginPattern("https://*.example2.com");
config.addAllowedHeader("*");
config.addAllowedMethod(HttpMethod.OPTIONS);
config.addAllowedMethod(HttpMethod.HEAD);
config.addAllowedMethod(HttpMethod.PATCH);
config.addAllowedMethod(HttpMethod.GET);
config.addAllowedMethod(HttpMethod.POST);
config.addAllowedMethod(HttpMethod.PUT);
config.addAllowedMethod(HttpMethod.DELETE);
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
- 使用 @CrossOrigin 注解
@CrossOrigin(origins = "https://www.example.com", methods = {
RequestMethod.OPTIONS, RequestMethod.GET, RequestMethod.POST})
@GetMapping(value = "/account/user")
public Result<User> getUserInfo(String sUserId) {
}
- 使用 WebMvcConfigurer 實作
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("https://www.example.com")
.allowedMethods("*");
}
}