代碼這種東西就是得不斷的使用窝革,如果長時間不用就會生疏。今天偶然間吕座,有人問我跨域的原理和怎么解決聊闯,說了一下,但是總是感覺還是差了點什么米诉,特此溫習(xí)一下菱蔬。
跨域的產(chǎn)生
最根本的原因就是瀏覽器的同源策略,所謂"同源"指的是"三個相同" 協(xié)議相同史侣、域名相同拴泌、端口相同,違反一個就會產(chǎn)生跨域問題惊橱。
請求的分類(簡單請求和非簡單請求)
- 請求方法是以下三種方法之一:HEAD,GET,POST蚪腐;
- HTTP的頭信息不超出以下幾種字段:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type(只限于三個值application/x-www-form-urlencoded、 multipart/form-data税朴、text/plain)
凡是不同時滿足上面兩個條件回季,就屬于非簡單請求。
解決跨域問題的方式
- JSONP 方式
- 代理請求方式
- CORS 方式
1正林、JSONP 方式 (只能是 get )
-
實現(xiàn)原理
image.png 客戶端網(wǎng)頁通過添加一個
function addScriptTag(src){
var script = document.createElement('script');
script.setAttribute('type','text/javascript');
script.src = src;
document.body.appendChild(script);
}
window.onload = function (){
addScriptTag('http://example.com/ip?callback=foo');
}
function foo (data) {
console.log('response data:'+JSON.stringify(data));
}
請求時泡一,接口地址是作為構(gòu)架出的腳本標(biāo)簽的src的,這樣觅廓,當(dāng)腳本標(biāo)簽構(gòu)建出來時鼻忠,最終的src是接口返回的內(nèi)容;
- 服務(wù)器端對應(yīng)的接口在返回參數(shù)外面添加函數(shù)包裹層
foo({ 'test':'testData' });
2杈绸、CORS 方式
cors是一個W3C標(biāo)準(zhǔn)帖蔓,全稱是--跨域資源共享,其實所有的瀏覽器ajax請求都是基于CORS機制的瞳脓,只是我們可能平時并不關(guān)心而已(所以說其實現(xiàn)在CORS解決方案主要是考慮后臺該如何實現(xiàn)的問題 )塑娇。
3、方向代理
通過把本地一個url前綴映射到要跨域訪問的web服務(wù)器上劫侧,就可以實現(xiàn)跨域訪問埋酬。
ajax跨域的表現(xiàn)
- 第一種
No 'Access-Control-Allow-Origin' header is present on the requested resource,并且The response had HTTP status code 404
原因:本次請求時‘非簡單請求’,所以請求會預(yù)先發(fā)送一個options請求;但是服務(wù)器端沒有允許options請求奇瘦,導(dǎo)致無法找到對應(yīng)的接口地址
解決方案:服務(wù)器允許options請求 - 第二種
No 'Access-Control-Allow-Origin' header is present on the requested resource,并且The response had HTTP status code 405
原因:后臺方法允許OPTIONS請求,但是一些配置文件中(如安全配置),阻止了OPTIONS請求,才會導(dǎo)致這個現(xiàn)象。
解決方案: 后端關(guān)閉對應(yīng)的安全配置劲弦。 - 第三種
No 'Access-Control-Allow-Origin' header is present on the requested resource,并且status 200耳标。
原因:服務(wù)器端后臺允許OPTIONS請求,并且接口也允許OPTIONS請求,但是頭部匹配時出現(xiàn)不匹配現(xiàn)象;
解決方案: 后端增加對應(yīng)的頭部支持 - 第四種
heade contains multiple values ','
原因:后臺響應(yīng)的http頭部信息有兩個Access-Control-Allow-Origin:邑跪,服務(wù)器端在項目的配置文件中配置了一次origin次坡,然后在代碼中有手動的添加了一次origin
解決方案:建議刪除代碼中手動添加的,只用項目配置中的即可