1. 程式人生 > >web開發前後端分離帶來的跨域問題

web開發前後端分離帶來的跨域問題

一次開發,專案要求前後端分離,這種模式,會帶來一些跨域的問題。首先,jsp,freemarker等等服務端模板都沒法用了,所有的請求必須是通過ajax來完成,ajax跨域,有一種解決辦法,就是通過jsonp的方式,但是這種方式,只適合get請求,對於post請求,就愛莫能助了,還得前後端配合,前端使用ajax,後端增加跨域配置:

一、跨域問題:

Failed to load http://10.119.9.167:8080/login: No 'Access-Control-Allow-Origin' header is 
present on the requested resource. Origin 'http://10.119.9.167' is therefore not allowed 
access. The response had HTTP status code 405.

這種問題,就是由於服務端,預設不接收來自本伺服器和埠以外的請求(http schema協議不同,host不同,port不同),這裡如果前端頁面和ajax請求還在本機上,只是埠不一樣,那麼服務端SpringBoot可以做如下修改:

package com.xxx.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
@Configuration
public class WebMvcConfiguration extends WebMvcConfigurationSupport{
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("GET","POST","DELETE","PATCH")
                .allowCredentials(true)
                .maxAge(3600);
    }
}

在這個配置中,設定了接收所有外部host的請求,包括GET,POST,DELETE,PATCH請求。

二、 還是跨域問題:

Blocked a frame with origin "http://10.119.9.167" from accessing a cross-origin frame.

這裡需要通過nginx來做一個反向代理,將我們的靜態頁面頁面,部署到nginx->html目錄下,服務端請求需要做一個反向代理:

location  \.(html|json)$ {
    root   html/webapp;
    index  index.html index.htm;
}

location ~ /webserver {
    proxy_pass   http://127.0.0.1:8080;
}

這種配置就利用nginx把兩個不同域的請求,整合到了一個域,前端頁面在nginx->html->webapp目錄下 ,頁面上http://127.0.0.1/webserver/xxx的請求就會轉到我們的伺服器端的8080上。

nginx實現了動靜分離,服務端只需提供restful介面。

三、跨域涉及到的session問題:

前面兩個步驟,解決了跨域介面請求的問題,如果前後端涉及到登入,而且有許可權控制,那麼在登入之後,不同域之間,預設是不會帶上cookie的,如果登入成功,我們接下來請求的時候,還是會遇到403或者405的錯誤,那麼就是我們的ajax請求預設沒有帶上cookie,解決辦法就是加上一個引數:xhrFields:{withCredentials:true},如下所示:

$.ajax({
  url:config.url +"/model/"+id,
  type:'get',
  data:{},
  xhrFields:{withCredentials:true},
  success:function(data){
	  //填充表單
	  if(data){
		  $("#ff").form("load",data);
	  }   
  },
  error:function(){

  }
});

如果使用的angulerjs,那麼需要作出如下配置:

$httpProvider.defaults.withCredentials = true; 

經過這三個步驟,前後端分離帶來的跨域問題就徹底解決了。