現(xiàn)在咱們一起來討論瀏覽器跨域請求數(shù)據(jù)的相關(guān)問題。說這樣可能不是很標(biāo)準(zhǔn),因?yàn)榫芙^跨域請求數(shù)據(jù)并不是瀏覽器所獨(dú)有的,之所以會出現(xiàn)跨域請求不了數(shù)據(jù),是因?yàn)闉g覽器基本都實(shí)現(xiàn)了一個(gè)叫"同源策略"的安全規(guī)范。該規(guī)范具體是什么呢?我們在MDN上找到了一份資料,地址如下:
專注于為中小企業(yè)提供做網(wǎng)站、成都做網(wǎng)站服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)衡山免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動了數(shù)千家企業(yè)的穩(wěn)健成長,幫助中小企業(yè)通過網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。
瀏覽器同源策略講解
總的來說,當(dāng)A網(wǎng)址和B網(wǎng)址在 協(xié)議 、 端口 、 域名 方面存在不同時(shí),瀏覽器就會啟動同源策略,拒絕A、B服務(wù)器之間進(jìn)行數(shù)據(jù)請求。
說了同源策略,紙上得來終覺淺,絕知此事要躬行,到底同源策略是怎么體現(xiàn)的呢?下面我將結(jié)合代碼一步一步進(jìn)行演示。
1、A服務(wù)器請求不了B服務(wù)器的情況
既然是跨域,我就假設(shè)我有兩個(gè)域名,分別是 A 和 localhost , A 表示小編在阿里云上主機(jī)域名, localhost 顧名思義就是小編的開發(fā)機(jī)器了。我們想象這樣一個(gè)場景,在 localhost 上部署一個(gè) index.html 文件,在 A 服務(wù)器上部署一個(gè)簡單的 spring-boot 后臺服務(wù),并提供一個(gè)簡單的接口暴露給 index.html 文件調(diào)用,最后瀏覽器請求 localhost 的 index.html 文件,看瀏覽器提示什么?
index.html
<!DOCTYPE html>
<html>
<head>
<title>測試跨域訪問</title>
<meta charset="utf-8"/>
</head>
<body>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$.ajax({
type : "get",
async : true,
url : "http://A/hello/map/getUser.json",// 請求A服務(wù)器上的接口
type : "json",
success : function(data) {
// 打印返回的數(shù)據(jù)
console.log("success,and return data is " + data);
}
});
});
</script>
<h3>hello world</h3>
</body>
</html>
瀏覽器上請求 index.html 文件,顯示如下:

可以發(fā)現(xiàn),請求被瀏覽器給拒絕了,提示我們不允許跨域請求數(shù)據(jù),很難受,怎么解決呢?
2、使用 jsonp 解決跨域請求
首先講下原理,jsonp解決跨域問題主要利用了 <script> 標(biāo)簽的可跨域性,也就是 src 屬性中的鏈接地址可以跨域訪問的特性,因?yàn)槲覀兘?jīng)常將 src 屬性值設(shè)置為cdn的地址,已加載相關(guān)的js庫。
index.html
<!DOCTYPE html>
<html>
<head>
<title>測試跨域訪問</title>
<meta charset="utf-8" />
</head>
<body>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$.ajax({
type : "get",
async : true,
jsonp : "callbackName",// 后端接口參數(shù)名
jsonpCallback : "callbackFunction", // 回調(diào)函數(shù)名
url : "http://A/hello/map/getUser.json",
dataType : "jsonp", // 數(shù)據(jù)格式為 jsonp
success : function(data) {
console.log("success");
}
});
});
</script>
<script type="text/javascript">
var callbackFunction = function(data) {
alert('接口返回的數(shù)據(jù)是:' + JSON.stringify(data));
};
</script>
</body>
</html>
A 服務(wù)器上的接口代碼為:
/**
*
* The class JsonBackController.
*
* Description:該控制器返回一串簡單的json數(shù)據(jù),json數(shù)據(jù)由一個(gè)簡單的User對象組成
*
* @author: huangjiawei
* @since: 2018年6月12日
* @version: $Revision$ $Date$ $LastChangedBy$
*
*/
@RestController
@RequestMapping(value = "/map")
public class JsonBackController {
private static final Logger logger = LoggerFactory.getLogger(JsonBackController.class);
/**
* 解決跨域請求數(shù)據(jù)
* @param response
* @param callbackName 前端回調(diào)函數(shù)名
* @return
*/
@RequestMapping(value = "getUser.json")
public void getUser(HttpServletResponse response, @RequestParam String callbackName) {
User user = new User("huangjiawei", 22);
response.setContentType("text/javascript");
Writer writer = null;
try {
writer = response.getWriter();
writer.write(callbackName + "(");
writer.write(user.toString());
writer.write(");");
} catch (IOException e) {
logger.error("jsonp響應(yīng)寫入失敗! 數(shù)據(jù):" + user.toString(), e);
} finally {
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
logger.error("輸出流關(guān)閉異常!", e);
}
writer = null;
}
}
}
}
后端傳入一個(gè)參數(shù) callbackName 回調(diào)函數(shù)名,然后返回一段js代碼給前端,js代碼格式如下:
callbackName + ( data ) + ;
瀏覽器請求 localhost 服務(wù)器上的 index.html 文件,結(jié)果如下:

上面這種方式是通過 jquery + jsonp 解決跨域問題的,剛剛不是說可以用 <script> 標(biāo)簽的 src 屬性嗎?四的。
localhost 服務(wù)器上的 index.html
<!DOCTYPE html>
<html>
<head>
<title>測試跨域訪問</title>
<meta charset="utf-8" />
</head>
<body>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript">
var callbackFunction = function(data) {
alert('接口返回的數(shù)據(jù)是:' + JSON.stringify(data));
};
</script>
<script type="text/javascript" src="http://A/hello/map/getUser.json?callbackName=callbackFunction"></script>
</body>
</html>瀏覽器顯示效果和上面一致。但此處需要注意的是, src 表示引入一個(gè)js文件,由于是直接調(diào)用接口,而接口返回的數(shù)據(jù)又剛好是一段js代碼,故能被執(zhí)行。另外,第二個(gè) <script> 標(biāo)簽順序不能顛倒,不然會出現(xiàn) callbackFunction 函數(shù)找不到的情況。
工程代碼地址 : https://github.com/SmallerCoder/jsonpDemo
最后總結(jié)下,解決跨域的方案有很多種,jsonp只是其中一種,具體情況需要具體分析。希望此文對你有幫助,謝謝閱讀,歡迎github給顆 start ,么么噠!也希望大家多多支持創(chuàng)新互聯(lián)。
文章名稱:springboot+jsonp解決前端跨域問題小結(jié)
鏈接分享:http://chinadenli.net/article2/jhjsic.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供ChatGPT、手機(jī)網(wǎng)站建設(shè)、定制開發(fā)、企業(yè)網(wǎng)站制作、移動網(wǎng)站建設(shè)、App設(shè)計(jì)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)