解決跨域的兩種方案
一、跨域與同源策略
跨域,通俗地講,是指一個服務A的客戶端請求另一個服務B的資料。下面給出了跨域的圖示。
在上面這個圖中,描述了客戶端與服務A關係,也就是說,客戶端不允許對服務A以外的服務進行訪問。這就是典型的跨域問題。通常同源策略與跨域緊密聯絡在一起。同源策略,它是由Netscape提出的一個著名的安全策略。現在所有支援JavaScript 的瀏覽器都會使用這個策略。所謂同源是指,域名,協議,埠相同。當一個瀏覽器的兩個tab頁中分別開啟來 百度和谷歌的頁面。當瀏覽器的百度tab頁執行一個指令碼的時候會檢查這個指令碼是屬於哪個頁面的,即檢查是否同源,只有和百度同源的指令碼才會被執行。如果非同源,那麼在請求資料時,瀏覽器會在控制檯中報一個異常,提示拒絕訪問。通常這個異常以下面的形式存在著:
Cross-Origin Read Blocking (CORB) blocked cross-origin response
二、跨域的情況
三、json與jsonp
json格式:
{
“message”:“獲取成功”,
“state”:“1”,
“result”:{“name”:“工作組1”,“id”:1,“description”:“11”}
}
jsonp格式:
callback({
“message”:“獲取成功”,
“state”:“1”,
“result”:{“name”:“工作組1”,“id”:1,“description”:“11”}
})
看出來區別了吧,在url中callback傳到後臺的引數是神馬callback就是神馬,jsonp比json外面有多了一層,callback()。這樣就知道怎麼處理它了。於是修改後臺程式碼。
Jsonp(JSON with Padding) 是 json 的一種"使用模式",可以讓網頁從別的域名(網站)那獲取資料,即跨域讀取資料。注意:Jsonp只支援get請求。
四、跨域處理程式碼實現
1、ajax的Jsonp方式
(1)前端程式碼
$(document).ready(function(){
var url=“http://localhost:8080/test/userList/listUserInfos.action”;
$.ajax({
url:url,
dataType:‘jsonp’,
jsonp:“callback”, //Jquery生成驗證引數的名稱
processData: false,
type:‘get’,
success:function(data){
console.info(data);
},
error:function(XMLHttpRequest, textStatus, errorThrown) {
alert(XMLHttpRequest.status);
alert(XMLHttpRequest.readyState);
alert(textStatus);
}});
});
(2)後臺程式碼
@ResponseBody
@RequestMapping(value = “/listUserInfos.action”)
public String listUserInfos(@RequestParam(“callback”) String callback) throws Exception {
UserInfo user = new UserInfo();
user.setUserName(“yzh”);
user.setPassword(“123”);
return callback+"("+JSONObject.toJSONString(user)+")";
}
說明:在這個介面中,使用了RequestParam 註解接收callback 引數,我們在客戶端請求中可以注意到callback 的內容:http://localhost:8083/test/userList/listUserInfos.action?callback=jsonp1541555710866
2、nginx的反向代理解決跨域問題
第一步:Tomcat叢集配置
server {
listen 8088;
server_name 192.168.154.4 yzh.com.cn;
#location / {
# root D:\software_package\nginx-1.7.7\html;
# root E:/hphg/tempFile;
# index index.html index.htm;
#}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
location /yx-web/ {
proxy_pass http://192.168.154.4:8080/yx-web/;
}
location /yx-web2/ {
proxy_pass http://192.168.154.4:8080/yx-web/;
}
location /test/ {
proxy_pass http://192.168.154.4:8080/test/;
}
location /test2/ {
proxy_pass http://192.168.154.4:8082/test/;
}
location /test3/ {
proxy_pass http://192.168.154.4:8083/test/;
}
#引入js靜態資源
location ~ \.(js)$ {
root D:/nginx_static_resources/test/js;
}
#引入css靜態資源
location ~ \.(css)$ {
root D:/nginx_static_resources/test/css;
}
}
第二步:編寫jsp檔案
<%@ page language=“java” contentType=“text/html; charset=utf-8”
pageEncoding=“utf-8”%>
<span>hello world!</span>
說明:url需要寫成反向代理中的代理地址,這是nginx能解決跨域問題的原因。
第三步:編寫contoller類
@ResponseBody
@RequestMapping(value = “/listUserInfos2.action”)
public UserInfo listUserInfos2() throws Exception {
UserInfo user = new UserInfo();
user.setUserName(“yzh2”);
user.setPassword(“123”);
return user;
}
第四步:測試
在瀏覽器的位址列中輸入http://yzh.com.cn:8088/test2/index.jsp,即可看到瀏覽器的控制檯列印的使用者資訊,說明跨域獲取資料成功。