Springboot解決ajax跨域的三種方式


1.同源策略 

1.1 含義

  ajax出現請求跨域錯誤問題,主要原因就是因為瀏覽器的“同源策略”;1995年,同源政策由 Netscape 公司引入瀏覽器。目前,所有瀏覽器都實行這個政策。

最初,它的含義是指,A網頁設置的 Cookie,B網頁不能打開,除非這兩個網頁"同源"。所謂"同源"指的是"三個相同"。

  • 協議相同
  • 域名相同
  • 端口相同

  舉例來說,http://www.example.com/dir/page.html這個網址,協議是http://,域名是www.example.com,端口是80(默認端口可以省略)。它的同源情況如下:

  • http://www.example.com/dir2/other.html:同源
  • http://example.com/dir/other.html:不同源(域名不同)
  • http://v2.www.example.com/dir/other.html:不同源(域名不同)
  • http://www.example.com:81/dir/other.html:不同源(端口不同)

1.2 目的

  同源策略的目的,是為了保證用戶信息的安全,防止惡意的網站竊取數據。

  設想這樣一種情況:A網站是一家銀行,用戶登錄以后,又去瀏覽其他網站。如果其他網站可以讀取A網站的 Cookie,會發生什么?很顯然,如果 Cookie 包含隱私(比如存款總額),這些信息就會泄漏。更可怕的是,Cookie 往往用來保存用戶的登錄狀態,如果用戶沒有退出登錄,其他網站就可以冒充用戶,為所欲為。因為瀏覽器同時還規定,提交表單不受同源政策的限制。

  由此可見,"同源策略"是必需的,否則 Cookie 可以共享,互聯網就毫無安全可言了。

1.3 限制范圍

  隨着互聯網的發展,"同源政策"越來越嚴格。目前,如果非同源,共有三種行為受到限制。

(1) Cookie、LocalStorage 和 IndexDB 無法讀取。

(2) DOM 無法獲得。

(3) AJAX 請求不能發送。

2.解決Ajax請求不能發送的問題

  本文只關注Ajax請求跨域問題,想了解更多可以參考:http://www.ruanyifeng.com/blog/2016/04/same-origin-policy.html 

  同源政策規定,AJAX請求只能發給同源的網址,否則就報錯。

  除了架設服務器代理(瀏覽器請求同源服務器,再由后者請求外部服務),有三種方法規避這個限制。

  • JSONP
  • WebSocket
  • CORS:(H5中的新特性:Cross-Origin Resource Sharing(跨域資源共享)。通過它,我們的開發者(主要指后端開發者)可以決定資源是否能被跨域訪問。cors是一個w3c標准,它允許瀏覽器(目前ie8以下還不能被支持)像我們不同源的服務器發出xmlHttpRequest請求,我們可以繼續使用ajax進行請求訪問)

  本文中我們使用第三種方式來解決在Springboot項目中的跨域問題。前端發出Ajax請求訪問Springboot(如在http://127.0.0.1:8086web項目中訪問http://127.0.0.1:8866)服務時,Ajax跨域請求報錯如下:

    $.ajax({
            url : "http://127.0.0.1:8866/index",
            type : "GET",
            dataType : "text",
            success : function(msg) {
                $("#box").html(msg);
                alert(msg);
            }
        });

  Access to XMLHttpRequest at 'http://127.0.0.1:8866/' from origin 'http://127.0.0.1:8086' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

  在http://127.0.0.1:8866這個服務中,我們有三種解決方式:

2.1注解方式

  在需要跨域的Controller層的類或方法上加上注解:@CrossOrigin。這樣就可以指定該controller中所有方法或某個方法處理所有或只來自http://127.0.0.1:8086中的請求。

@Controller
@CrossOrigin//@CrossOrigin(origins = "http://127.0.0.1:8086", maxAge = 3600)
public class ApiController {

    //@CrossOrigin
    @GetMapping(value = "/index")
    public String index(HttpServletRequest request) {
        request.getSession().setMaxInactiveInterval(60*30);

        return "index";
    }
}

2.2 過濾器方式

  修改返回請求頭信息:

@Component
public class CorsFilter implements Filter {

    private static final Logger logger = LoggerFactory.getLogger(CorsFilter.class);

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {

        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, HEAD");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers",
                "access-control-allow-origin, authority, content-type, version-info, X-Requested-With");

        chain.doFilter(req, res);
    }

    @Override
    public void destroy() {

    }

}

2.3 繼承WebMvcConfigurerAdapter,重寫addCorsMappings方法:

@Component
public class WebMvcConfig extends WebMvcConfigurerAdapter {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
        .allowCredentials(true)
        .allowedOrigins("*")
        .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE")
        .maxAge(3600) 
        .allowedHeaders("*");
    }
}

OVER!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM