跨域那點事~
阿新 • • 發佈:2018-12-08
自從做了前後端分離專案以後,就遇到了跨域問題.一直也沒有深入自己去測試,反正能解決就行了,今天自己寫了一系列測試,得到了java解決跨域問題的多種方法;
1.首先是基本沒用過的jsonp方式:(缺點:麻煩,只支援GET請求)
$("#btn3").click(function () { $.ajax({ url: "http://localhost:9090/test3", type: "get", dataType: "jsonp", //這裡指定請求後臺伺服器返回型別jsonp // jsonpCallback: "gao", //指定請求地址後面callback的值 // jsonp:"callback", //指定jsonp請求地址的引數名,預設callback success: function (data) { alert(data); } }); });
如果上面不指定jsonpCallback的請求值時,會預設生成隨機的請求值;如下:
http://localhost:9090/test3?callback=jsonp1536806347498
後臺處理的話,就要在引數返回時,使用jsonp請求值包裹返回值,如 jsonp1536806347498(...);
@GetMapping("/test3") public void tt3e(HttpServletRequest request, HttpServletResponse response) throws IOException { String callback = request.getParameter("callback"); String result = new ObjectMapper().writeValueAsString(Arrays.asList(1, 1, 1, 1)); String now = callback + "(" + result + ")"; response.getWriter().write(now); }
2.後臺返回引數header新增跨域引數;(全是優點)
這種前臺不用做任何操作,只要後臺進行一些新增引數即可;方式有以下幾種;
第一種,新增過濾器,攔截器方式:
public class MyFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletResponse response = (HttpServletResponse) servletResponse; response.setCharacterEncoding("utf-8"); response.setHeader("Access-Control-Allow-Origin", "*"); // 解決跨域訪問報錯 response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE"); response.setHeader("Access-Control-Max-Age", "3600"); // 設定過期時間 response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, client_id, uuid, Authorization"); response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // 支援HTTP 1.1. response.setHeader("Pragma", "no-cache"); // 支援HTTP 1.0. response.setHeader("Expires", "0"); filterChain.doFilter(servletRequest, servletResponse); } @Override public void destroy() { } }
public class MyConfig implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
return true;
}
}
這種方式不管你已何種方式請求,跨域或者不跨域,在返回引數header引數中,都可以看到以下引數:
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, client_id, uuid, Authorization
Access-Control-Allow-Methods: POST, PUT, GET, OPTIONS, DELETE
Access-Control-Allow-Origin: *
Access-Control-Max-Age: 3600
Cache-Control: no-cache, no-store, must-revalidate
Content-Type: application/json;charset=UTF-8
Date: Thu, 13 Sep 2018 02:50:53 GMT
Pragma: no-cache
Transfer-Encoding: chunked
因為用下面的方式跨域時,本地用postman測試時候,因為沒有這些引數,一直以為沒有生效,所以一直採用這種方式,沒有敢用其他方式.......其實下面方式也是生效的,只有跨域請求的時候會在返回引數中帶有這些跨域引數;
第二種,springboot直接重寫跨域配置,這種方式比較簡單,推薦:
public class MyCros implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("*");
}
}
第三種:在類或者方法上新增@CrossOrigin註解;看到網上有在ssm專案中遇到不生效的問題,看到解決辦法有的因為@RequestMapping註解中沒有指定method請求方式造成的,只要新增get或post等引數就可以了.我在springboot中沒有出現這種問題;