为什么有跨域问题
跨域问题是浏览的一种保护机制,是前端的问题,后端的服务相互调用不存在跨域问题(后端httpClient 前端ajax),当浏览器访问的地址跟ajax访问的地址不一样的时候就会产生跨域问题。
1.jsonp 前端
jsopn的请求方式只能是get请求,post请求不支持jsonp的请求.每个ajax的请求都必须是jsonp格式的
$.ajax({
url:'http://10.10.37.234:4567/visitorDeatil/submit',
dataType:'jsonp',
type:"get",
contentType:'application/json',
data:{
contacts:"dfdf",
company:"fdfd",
duty:"dsfsdf",
remak:"fdsf",
phone:"fsdf",
systemCode:"1"
},
success:function(data) {
callback(data)
}
})
//这样才能拿到数据
functioncallback(data){
alert(data.msg)
}
Jsonp请求路径上有callback函数,所以在服务中返回数据的时候,跟普通的请求的返回数据是不一样的,要返回一个js格式的数据,相当于把数据放到callback的函数里面返回.
@RequestMapping(value = "/submit", method = RequestMethod.GET)
@ResponseBody
public Objectsubmit(VisitorProbationDetail visitor, String callback) throws Exception {
if (StringUtils.isEmpty(visitor.getContacts()) ||StringUtils.isEmpty(visitor.getCompany())
|| StringUtils.isEmpty(visitor.getPhone())) {
String result = callback + "(" + JSONObject.toJSON(ApiResult.build(0, "信息不完整!!!")).toString() + ");";
returnresult;
}
String msg = visitorService.save(visitor);
if (0 == msg.length()) {
String result = callback + "(" + JSONObject.toJSON(ApiResult.build(200, "恭喜您申请成功!!!")).toString() + ");";
returnresult;
}
returncallback + "(" +JSONObject.toJSON(ApiResult.build(0, msg)).toString()+ ");";
}
于普通请求返回数据不同的地方就是把json数据做了一层封装,封装到callback函数里面.
2.cros 后端设置
这种方式后端设置一下就可以了,前端无感知,各种请求都支持也比较方便
方式一 :在映射的方法上添加注解@CrossOrigin
@CrossOrigin
@RequestMapping(value = "users", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<JsonResult> queryAllUser() {
JsonResult jsonResult = new JsonResult();
try {
List<User> users = userService.queryAllUser();
jsonResult.setResult(users);
jsonResult.setStatus("success");
} catch (Exception e) {
jsonResult.setResult(e.getMessage());
jsonResult.setStatus("success");
}
return ResponseEntity.ok(jsonResult);
}
方式二:配置全局CROS配置
@Configuration
public class CrosConfig {
@Bean
public WebMvcConfigurer crosConfigurer(){
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "POST", "DELETE", "PUT", "OPTIONS")
.allowCredentials(false).maxAge(3600);
}
};
}
}
3.ngnix反向代理
server {
#监听的端口号
listen 80;
#拦截的域名
server_name bowei.com;
#拦截以a开头的
location /b {
#代理到
proxy_pass http://bowei.com:8082/;
index index.html index.htm;
}
location /a {
proxy_pass http://bowei.com:8081/;
index index.html index.htm;
}
}
ajax访问的地址:
http://bowei.com:8081/ 直接访问这个地址是有跨域问题的
把访问地址改成 bowei.com/a 就不会有跨域问题。
原理:ajax 访问bowei.com/a地址 ngnix拦截域名bowei.com的80端口根据配置/a的规则反向代理到 http://bowei.com:8081/这个地址,ngnix访问这个地址是不会有跨域问题的。跨域问题是浏览器的保护机制。
4.通过网关解决
有很多微服务都需要跨域处理的时候可以在最外层的网关处理就可以了。其他的微服务不需要处理,微服务处理了网关也处理了就会出现问题。
详情 https://blog.youkuaiyun.com/qq_24641227/article/details/93474285