天天看點

開發中,如何解決跨域問題?

作者:KristenGe

跨域問題

跨域問題是指浏覽器在執行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("*");
    }
}