做前端的童鞋必然都會碰到這么一個問題够坐,跨域。這對于不懂這個概念的開發(fā)者是個很痛苦的事情恤煞,因為你的控制臺會報這么一個錯誤:
相信大家對于這個報錯都不陌生的趾撵。那么問題來了侄柔,為什么會報這個錯誤呢?這就要涉及到同源策略了占调,具體什么是同源策略我不多做解釋暂题,自己上網(wǎng)查,這里不做贅述究珊。
在這里我只做簡單的概述薪者,怎樣才會造成跨域問題: 調(diào)用接口的時候,當(dāng)你調(diào)用接口的 域名|協(xié)議|端口 和你瀏覽器的 域名|協(xié)議|端口 不一致時苦银,就會造成跨域問題啸胧。簡單來說赶站,在你在調(diào)用接口或者請求資源的時候幔虏,同源策略就相當(dāng)于法律纺念,一旦觸犯,就會有警察去制止你的行為想括。所以陷谱,簡單來說,我們的目標(biāo)就是把我們調(diào)用接口這件事變得合法瑟蜈。
這里我們先從JS的ajax實現(xiàn)開始闡述
<script type="text/javascript">
function loadXMLDoc() {
var xmlhttp;
if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else {// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
//readyState==4 表示 請求已完成烟逊,且響應(yīng)已就緒 xmlhttp.status==200 表示服務(wù)器響應(yīng)成功
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
// 返回的信息在 xmlhttp.responseText里面存著呢
document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
}
}
// 用xmlhttp對象開啟一個鏈接 true->異步 false->同步
xmlhttp.open("GET","接口地址",true);
// 發(fā)送請求
xmlhttp.send();
}
</script>
上面代碼就用js簡單的完成了一個ajax請求了。我們看到有個對象xmlhttp,它是由XMLHttpRequest這個構(gòu)造函數(shù)創(chuàng)建的铺根。我們的所有有關(guān)的ajax請求以及相應(yīng)等信息都包含在這個對象之中宪躯。
在不觸犯同源策略的情況下,這樣做事沒問題的位迂。但是一旦觸犯的話访雪,又會像最上面的那張圖一樣。這里掂林,我們的第一個目標(biāo)臣缀,就是干掉這個錯誤!
方法一:
我們仔細(xì)看下這個錯誤:
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8020' is therefore not allowed access.
大概我們可以看到上面是這么一個意思:請求頭中沒有 'Access-Control-Allow-Origin'的信息泻帮,所以 源'http://127.0.0.1:8020'是不被允許的精置。嘖嘖嘖,感謝控制臺提示到這份上了锣杂,我想大家應(yīng)該明白了脂倦,問題出在了哪里。在后臺沒有設(shè)置對應(yīng)的 'Access-Control-Allow-Origin' 信息元莫,所以請求不被允許狼讨。所以,這個時候需要你的后臺產(chǎn)生對應(yīng)的配置信息柒竞。請看下面:
Access-Control-Allow-Origin: 允許跨域的url(一般是你瀏覽器的域名政供,* 表示所有)
Access-Control-Allow-Credentials: true (是否允許攜帶cookie,ajax默認(rèn)是不帶cookie信息的朽基,但可配置)
Content-Type: text/html; charset=utf-8 (相應(yīng)內(nèi)容數(shù)據(jù)類型以及編碼類型)
OK布隔,當(dāng)你的后臺配置了對應(yīng)的信息頭以后,你的跨域問題應(yīng)該已經(jīng)得到了解決稼虎。不過對于我們目前的開發(fā)節(jié)奏來說衅檀,大多數(shù)采用的是封裝好的ajax庫去幫助我們更快速的進(jìn)行ajax請求,我們以jQuery的ajax為例
$.ajax({
// 請求方式 默認(rèn)是get
type: 'post',
// 地址
url: 'url',
// 對于get請求霎俩,這個沒必要去設(shè)置哀军,因為最后都是queryString的形式進(jìn)行發(fā)送
contentType: 'application/json', // 默認(rèn)是 application/x-www-form-urlencoded
data: { id: '1' },
// 允許攜帶cookie信息-這個需要和后臺協(xié)商沉眶,看是否需要 (可選)
// 注意: 服務(wù)器端 Access-Control-Allow-Credentials = true 時,參數(shù)Access-Control-Allow-Origin 的值不能為 '*' 杉适。
xhrFields: {
withCredentials: true
},
// 假設(shè)是跨域請求
crossDomain: true,
dataType: 'json', //默認(rèn)是json
success: function (res) {
// res返回的code不為 0 的 時候谎倔,說明你的請求有問題,這里和我們的主題沒太大關(guān)系
if (res.code === 0) {
console.log(res)
} else {
console.log(res.message)
}
},
error: function (err) {
console.log('注冊有誤')
}
})
這里我們再講下jQ的第二種避免跨域問題的方式-jsonp
$.ajax({
type:"get", //請求方式
async:true, //是否異步
url:"https://d.jd.com/lab/get",
dataType:"jsonp",
crossDomain:true,
success: function(res) {
console.log('success', res);
},
error: function(res) {
console.log('error', res);
}
});
這里我簡單概述下啥事jsonp(摘抄子百度) : JSONP(JSON with Padding)是JSON的一種“使用模式”猿推,可用于解決主流瀏覽器的跨域數(shù)據(jù)訪問的問題片习。
它其實是利用了<script>標(biāo)簽沒有跨域限制的漏洞去達(dá)到請求資源的目的,當(dāng)然這是要后臺進(jìn)行配合的蹬叭。這里有一篇不錯的文章可以進(jìn)行參考 : https://www.cnblogs.com/chenweichu/articles/7492460.html
這里其實我們不妨借助工具去實現(xiàn)我們的跨域行為(nginx反向代理)去利用第三方工具幫助我們?nèi)グl(fā)送請求藕咏,你可以理解這個第三方工具相當(dāng)類似于一個后臺服務(wù)應(yīng)用,而后臺服務(wù)之間接口的調(diào)用是不存在跨域問題的秽五。
有過vue-cli項目開發(fā)經(jīng)驗的童鞋應(yīng)該知道vue為我們提供了一個開發(fā)服務(wù)器孽查,這個開發(fā)服務(wù)器就代理發(fā)送了我們的請求,因此避免了跨域的問題坦喘。
文章講到這盲再,希望對你有幫助,有錯誤的話請指正起宽。