前後端分離,跨域請求
阿新 • • 發佈:2019-01-04
一.前言
跨域,指的是瀏覽器不能執行其他網站的指令碼。它是由瀏覽器的同源策略造成的,是瀏覽器施加的安全限制。
同源策略:請求的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);
}
}