在IDEA中有一套微服务,然后在webStorm中写前端代码,前端使用ajax访问Controller:
function getDate(){ var id=$("#id").val(); $.ajax({ type:"post", dataType:"json", url:"http://localhost:8081/index/test", data:{"id":id}, success:function (data){ alert(data.time); }, error:function (data){ alert(JSON.stringify(data)); } }) }
后端Controller会返回一个Map,执行没有问题,但是ajax一直执行error,F12发现出错: No 'Access-control-Allow-Origin' header is present on the requested resource。
查询后,发现是因为跨域了,跨域访问违反了同源策略!
同源:域名,协议,端口相同。
同源策略:浏览器的ajax只能访问跟它的html页面相同域名或IP的资源。
同源策略是浏览器的行为,是为了保护本地数据不被JavaScript代码获取回来的数据污染,因此拦截的是客户端发出的请求回来的数据接收,即请求发送了,服务器响应了,但是无法被浏览器接收。
前端的IP是localhost:63343,后端IP是localhost:8081,这样导致ajax能访问后端(只是简单的调用),但是不能获得其返回值!
第一种方法,还是没能接受,第二种方法成功了,第三种最简单!。
解决方法:
第一种:
使用ajax 的jsonp:
修改前端ajax:
function getDate(){ var id=$("#id").val(); $.ajax({ type:"post", dataType:"jsonp", jsonp:"callback", contentType:"application/jsonp;charset=utf-8", url:"http://localhost:8081/index/test", data:{"id":id}, success:function (data){
var data1=data["dataOne"]; alert(data1.time); }, error:function (data){ alert(JSON.stringify(data)); } }) }
修改后端Controller方法:
public String test(String id, String callback){ /* *执行serviceImpl */ return callback+"({dataOne:"+map+"})"; }
第二种,启动类里配置,类似于zuul网关配置,见参考二:
public static void main(String[] args) { SpringApplication.run(DemoUaaApplication.class, args); } @Bean public CorsFilter corsFilter() { final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); final CorsConfiguration config = new CorsConfiguration(); config.setAllowCredentials(true); // 允许cookies跨域 config.addAllowedOrigin("*");// 允许向该服务器提交请求的URI,*表示全部允许,在SpringMVC中,如果设成*,会自动转成当前请求头中的Origin config.addAllowedHeader("*");// 允许访问的头信息,*表示全部 config.setMaxAge(18000L);// 预检请求的缓存时间(秒),即在这个时间段里,对于相同的跨域请求不会再预检了 config.addAllowedMethod("*");// 允许提交请求的方法,*表示全部允许 config.addAllowedMethod("HEAD"); config.addAllowedMethod("GET");// 允许Get的请求方法 config.addAllowedMethod("PUT"); config.addAllowedMethod("POST"); source.registerCorsConfiguration("/**", config); return new CorsFilter(source); } }
第三种,在类前面配置:@CrossOgigin(origins="*",maxAge=3600)
@RestController @RequestMapping("index") @CrossOrigin(origins="*",maxAge=3600)
public class TestOne{
@RequestMapping("/test") public Map test(String id){ /* *执行serviceImpl */ return Map; }
}
参考一:https://segmentfault.com/a/1190000012469713
参考二:https://blog.csdn.net/m0_37556444/article/details/82832054