1. 程式人生 > >前後端分離,跨域請求

前後端分離,跨域請求

一.前言

跨域,指的是瀏覽器不能執行其他網站的指令碼。它是由瀏覽器的同源策略造成的,是瀏覽器施加的安全限制。

同源策略:請求的url地址,必須與瀏覽器上的url地址處於同域上,也就是域名,埠,協議相同

不同域名之間相互訪問對於前後端分離的專案來說,如果前端專案與後端專案部署在兩個不同的域下,那麼會引起跨域的問題。

二.現象

1.前端ajax請求後臺介面
   function getCk() {
       $.ajax({
           url: "http://localhost:8002"+"/getCk",
           type: 'GET'
, success: function (data) { layer.msg("結果:"+data); } }); }
2.後臺介面
	@GetMapping("/getCk")
    @ResponseBody
    public String getCk(){
        return "hello world";
    }
3.請求結果

Failed to load http://localhost:8002/getCk: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘

http://localhost:63342’ is therefore not allowed access.

三.解決方案

1.使用JSONP

1.前端程式碼

       $.ajax({
           url: "http://localhost:8002"+"/getCk2",
           type: 'GET',
           dataType: 'jsonp',
           success: function (date) {
               layer.msg("結果:"+date);
           }
       }
);

2.後端程式碼

 	@GetMapping("/getCk2")
    @ResponseBody
    public String getCk2(String callback){
        String result=callback+"("+ JSON.toJSONString("hello world2")+")";
        return result;
    }

3.結果
請求後的地址為:
http://localhost:8002/getCk2?callback=jQuery21404377760922496734_1546047342242&_=1546047342243

jsonp指定伺服器返回的資料型別為jsonp格式,可以看發起的請求路徑,自動帶了一個callback=xxx,xxx是jquery隨機生成的一個回撥函式名稱。

其原理跟 < scri pt> 指令碼請求一樣,因此使用jsonp時也只能使用GET方式發起跨域請求。跨域請求需要服務端配合,設定callback,才能完成跨域請求。所以不推薦使用

結果: hello word2

2.通過cors協議

(1) 使用crossOrigin註解

    @CrossOrigin
    @GetMapping("/getCk1")
    @ResponseBody
    public String getCk1(){
        return "hello world1";
    }

(2) 或者使用Filter攔截處理

@Component
public class Filter implements Filter {

    /*跨域請求配置*/
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;

        HttpServletRequest reqs = (HttpServletRequest) req;
        response.setHeader("Access-Control-Allow-Origin","*");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "5000");
        response.setHeader("Access-Control-Allow-Headers", "Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With,Authorization,Token");
        chain.doFilter(req, res);
    }
    @Override
    public void init(FilterConfig filterConfig) {}
    @Override
    public void destroy() {}
}

(3) 繼承webmvcconfigureradapter的方法

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**").allowedOrigins("*").allowedMethods("GET", "POST", "OPTIONS", "PUT")
                .allowedHeaders("Content-Type", "X-Requested-With", "accept", "Origin", "Access-Control-Request-Method",
                        "Access-Control-Request-Headers")
                .exposedHeaders("Access-Control-Allow-Origin", "Access-Control-Allow-Credentials")
                .allowCredentials(true).maxAge(3600);
    }
}