什么是跨域:
跨域问题来源于JavaScript的同源策略,即只有 协议+主机名+端口号 (如存在)相同,则允许相互访问。也就是说JavaScript只能访问和操作自己域下的资源,不能访问和操作其他域下的资源。跨域问题是针对JS和ajax的,html本身没有跨域问题,比如a标签、script标签、甚至form标签(可以直接跨域发送数据并接收数据)等
AJAX产生跨域原因:(3个问题同时满足 才可能产生跨域问题)
浏览器限制
跨域(协议,主机名,端口号中有一个不同就产生跨域)
XHR(XMLHttpRequest)请求
浏览器会先执行还是先判断跨域?
简单请求会先执行在判断,非简单请求先判断再执行
跨域问题如何解决
1. 使用jsonp解决网站跨域
前端代码
后端代码
@RequestMapping(value = “/ajaxB”, method = RequestMethod.GET)
public void ajaxB(HttpServletResponse response, String jsonpCallback) throws IOException {
JSONObject root = new JSONObject();
root.put(“errorCode”, “200”);
root.put(“errorMsg”, “登陆成功”);
response.setHeader(“Content-type”, “text/html;charset=UTF-8”);
PrintWriter writer = response.getWriter();
writer.print(jsonpCallback + “(” + root.toString() + “)”);
writer.close();
}
缺点:不支持post请求,代码书写比较复杂
2.使用HttpClient内部转发
后端代码
A项目进行转发到B项目
@RequestMapping("/forwardB")
@ResponseBody
public JSONObject forwardB() {
JSONObject result = HttpClientUtils.httpGet(“http://b.aa.com:8081/ajaxB”);
System.out.println(“result:” + result);
return result;
}
B项目代码
@RequestMapping("/ajaxB")
public Map<String, Object> ajaxB(HttpServletResponse response) {
response.setHeader(“Access-Control-Allow-Origin”, “*”);
Map<String, Object> result = new HashMap<String, Object>();
result.put(“errorCode”, “200”);
result.put(“errorMsg”, “登陆成功”);
return result;
}
3.使用设置响应头允许跨域
前端代码
后端代码
@RequestMapping("/ajaxB")
public Map<String, Object> ajaxB(HttpServletResponse response) {
response.setHeader(“Access-Control-Allow-Origin”, “");
Map<String, Object> result = new HashMap<String, Object>();
result.put(“errorCode”, “200”);
result.put(“errorMsg”, “登陆成功”);
return result;
}
response.setHeader(“Access-Control-Allow-Origin”, "”); 设置响应头允许跨域
如果在实际项目中,该代码建议放在过滤器中。
4.基于Nginx搭建企业级API接口网关
server {
listen 80;
server_name www.aa.com;
###A项目
location /a {
proxy_pass http://a.aa.com:8080/;
index index.html index.htm;
}
###B项目
location /b {
proxy_pass http://b.aa.com:8081/;
index index.html index.htm;
}
}
5.使用Zuul搭建微服务API接口网关