什麼是跨域:
跨域問題來源于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接口網關