2021-05-12 14:32:11
前端跨域請求jsonp實現
跨域問題來源於JavaScript的同源策略,即只有 協定+主機名+埠號 (如存在)相同,則允許相互存取,有一種不同即不能存取。也就是說JavaScript只能存取和操作自己域下的資源,不能存取和操作其他域下的資源。跨域問題是針對JS和ajax的,html本身沒有跨域問題,比如a標籤、script標籤、甚至form標籤(可以直接跨域傳送資料並接收資料)等 。
JSONP(JSON with Padding)是JSON的一種「使用模式」,可用於解決主流瀏覽器的跨域資料存取的問題。由於同源策略,一般來說位於 server1.example.com 的網頁無法與不是 server1.example.com的伺服器溝通,而 HTML 的<script> 元素是一個例外。利用 <script> 元素的這個開放策略,網頁可以得到從其他來源動態產生的 JSON 資料,而這種使用模式就是所謂的 JSONP。用 JSONP 抓到的資料並不是 JSON,而是任意的JavaScript,用 JavaScript 直譯器執行而不是用 JSON 解析器解析。
1
第一種:建立一個springboot的專案。
1、 開啟建立頁面 選擇File-new-project..
2、選擇建立的專案為spring initializr 進入springboot專案建立步驟(也可以選擇型別java,建立一個普通java專案)
3、輸入專案名字,選擇依賴web(根據專案需求選擇,此次需要),選擇存放目錄-完成(Finish)
2
第二種:建立一個簡單的javaweb專案。
1、直接開啟:https://jingyan.baidu.com/article/ff411625048acf12e482373a.html
2、或者百度搜尋:servlet類如何對映到url路徑 百度經驗
1
第一步:編寫被呼叫專案的controller。
1、需要整合springmvc,springboot專案整合web就包含springmvc,普通的servlet需要:
PrintWriter w = response.getWriter();w.print(json);
2、埠預設8080
3、controller程式碼如下所示
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
@RestController
public class TestController {
@RequestMapping("/bean")
public String testJson(HttpServletRequest request,
HttpServletResponse response, Map paramMap) {
String callback = request.getParameter("callback");
String id = request.getParameter("id");
String name = request.getParameter("name");
String sex = request.getParameter("sex");
String json = "{'id':" + id + ",'name':'" + name + "','sex':'" + sex
+ "'}";
if (callback != null) {
json = callback + "(" + json + ")";
}
return json;
}
}
4、啟動服務並測試:
http://localhost:8080/bean?id=2&name=張三&sex=男
2
第二步:呼叫專案的準備。1、新建一個javaweb專案2、在埠號設定為80203、編寫跨域呼叫程式碼,主要是頁面js的編寫1
第一種:原生的js實現跨域。
1、借助於原生javascript實現,具體程式碼如下所示:
window.onload = function () {
var script = document.createElement('script');
script.setAttribute("type","text/javascript");
script.src = 'http://localhost:8080/bean?callback=ajaxCallback&id=2&name=張三&sex=男';
document.body.appendChild(script);
}
function ajaxCallback(data) {
alert('response data: ' + JSON.stringify(data));
};
2
第二種:借助於jquery的getJSON實現。
具體程式碼如下所示:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>跨域測試</title>
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
</head>
<body>
<script>
$.getJSON("http://localhost:8080/bean?callback=?", {id:2,name:'李四',sex:'男'},
function(data) {
alert(data.id+data.name+data.sex);
});
</script>
</body>
</html>
3
第三種:借助於jquery的ajax實現。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>跨域測試</title>
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
</head>
<body>
<script>
$.ajax({
//設定請求型別
type:"get",
//請求超時時間
timeout:5000,
//設定請求地址
url: 'http://localhost:8080/bean',
//設定需要傳送的資料
data: {id:2,name:'李四',sex:'男'},
//定義此請求為跨域請求
dataType: 'jsonp',
//定義回撥函數
jsonpCallback:"callbackUser",
success: function (data) {
console.log("成功");
},
error: function (data) {
console.log(data)
}
})
function callbackUser(data){
alert("id:"+data.id+" name:"+data.name+" sex:"+data.sex);
}
</script>
</body>
</html>
4
第四種:主要是對三種的優化。
1、主要是去除jsonpCallback屬性,url中傳callback=?定義預設呼叫ajax的回撥函數。要與後台程式碼對應(String callback = request.getParameter("callback");)
2、呼叫計畫頁面如下所示:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>跨域測試</title>
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
</head>
<body>
<script>
$.ajax({
//設定請求型別
type:"get",
//請求超時時間
timeout:5000,
//設定請求地址
url: 'http://localhost:8080/bean?callback=?',
//設定需要傳送的資料
data: {id:2,name:'李四',sex:'男'},
//定義此請求為跨域請求
dataType: 'jsonp',
success: function (data) {
console.log("成功");
alert("id:"+data.id+" name:"+data.name+" sex:"+data.sex);
},
error: function (data) {
console.log(data)
}
})
</script>
</body>
</html>
1
1、jsonp實現的方式就是借助於script標籤的src屬性獲取資料,然後將資料作為引數傳給函數,解析資料。這一點我們需要結合後台callback + ?"(" + json + ")"可以看出一二。2、跨域問題的解決方案除了jsonp方式外還有一種CORS,與jsonp不同的是這是一種後台解決方案。相關文章