?
1.什么是跨域岂却?
本地域與服務端的域不一致井氢,是由瀏覽器同源策略限制的場景弦追,不同源即不同域,就是跨域花竞。
注意:協(xié)議端口不同造成的跨域劲件,前臺無能為力。 域僅僅是通過URL的首部來識別,而不會去嘗試判斷相同的IP對應著兩個域 零远。 或者兩個域是否在同一個IP上苗分。
2.什么是同源策略?
瀏覽器最核心也最基本的安全功能牵辣,如果缺少了同源策略摔癣,瀏覽器很容易受到XSS、CSFR等攻擊纬向。所謂同源是指"協(xié)議+域名+端口"三者相同供填。
只要 "協(xié)議+域名+端口" 任何一個不同都被當作不同的域。
3.跨域解決方案
(1)通過jsonp跨域
JSONP:
原理是:
動態(tài)插入script標簽罢猪,通過script標簽引入一個js文件,這個js文件載入成功后會執(zhí)行我們在url參數(shù)中指定的函數(shù)叉瘩,并且會把我們需要的json數(shù)據(jù)作為參數(shù)傳入膳帕。
由于同源策略的限制,XmlHttpRequest只允許請求當前源(域名薇缅、協(xié)議危彩、端口)的資源,為了實現(xiàn)跨域請求泳桦,可以通過script標簽實現(xiàn)跨域請求汤徽,然后在服務端輸出JSON數(shù)據(jù)并執(zhí)行回調函數(shù),從而解決了跨域的數(shù)據(jù)請求灸撰。
JSONP:json+padding(內填充)谒府,顧名思義,就是把JSON填充到一個盒子里
優(yōu)點:是兼容性好浮毯,簡單易用完疫,支持瀏覽器與服務器雙向通信。
缺點:只支持get债蓝。只支持http
JSONP的優(yōu)點是:它不像XMLHttpRequest對象實現(xiàn)的Ajax請求那樣受到同源策略的限制壳鹤;它的兼容性更好,在更加古老的瀏覽器中都可以運行饰迹,不需要XMLHttpRequest或ActiveX的支持芳誓;并且在請求完畢后可以通過調用callback的方式回傳結果。
JSONP的缺點則是:它只支持GET請求而不支持POST等其它類型的HTTP請求啊鸭;它只支持跨域HTTP請求這種情況锹淌,不能解決不同域的兩個頁面之間如何進行JavaScript調用的問題。
<script> function createJs(sUrl){ var oScript = document.createElement('script'); oScript.type = 'text/javascript'; oScript.src = sUrl; document.getElementsByTagName('head')[0].appendChild(oScript); } createJs('jsonp.js'); box({ 'name': 'test' }); function box(json){ alert(json.name); } </script>
總結:通過iframe的src屬性由外域轉向本地域莉掂,跨域數(shù)據(jù)即由iframe的window.name從外域傳遞到本地域葛圃。這個就巧妙地繞過了瀏覽器的跨域訪問限制,但同時它又是安全操作。
6库正、 跨域資源共享(CORS)
普通跨域請求:只服務端設置Access-Control-Allow-Origin即可曲楚,前端無須設置,若要帶cookie請求:前后端都需要設置褥符。
需注意的是:由于同源策略的限制龙誊,所讀取的cookie為跨域請求接口所在域的cookie,而非當前頁喷楣。
目前趟大,所有瀏覽器都支持該功能(IE8+:IE8/9需要使用XDomainRequest對象來支持CORS)),CORS也已經(jīng)成為主流的跨域解決方案铣焊。
CORS
服務器端對于CORS的支持逊朽,主要就是通過設置Access-Control-Allow-Origin來進行的。如果瀏覽器檢測到相應的設置曲伊,就可以允許Ajax進行跨域的訪問叽讳。
通過修改document.domain來跨子域
將子域和主域的document.domain設為同一個主域.前提條件:這兩個域名必須屬于同一個基礎域名!而且所用的協(xié)議,端口都要一致坟募,否則無法利用document.domain進行跨域
主域相同的使用document.domain
使用window.name來進行跨域
window對象有個name屬性岛蚤,該屬性有個特征:即在一個窗口(window)的生命周期內,窗口載入的所有的頁面都是共享一個window.name的,每個頁面對window.name都有讀寫的權限懈糯,window.name是持久存在一個窗口載入過的所有頁面中的
使用HTML5中新引進的window.postMessage方法來跨域傳送數(shù)據(jù)
還有flash涤妒、在服務器上設置代理頁面等跨域方式。個人認為window.name的方法既不復雜赚哗,也能兼容到幾乎所有瀏覽器她紫,這真是極好的一種跨域方法。
針對react版本^16.6.0有多種解決方案
方案一:package.json中加上proxy代理配置
在packge.json加入
“proxy”:{
'/app':{
"tatget":"http://server.sssss.com:8080/.....",
secure:false,
"changeOrigin":true,
}
}
axios
import axios from 'axios'
http.post = function(api, data){
return new Promise((resolve, reject) =>{
axios.post(api, params).then((tes)=>{resolve(res)})
})
}
http.get = function(api, data){
return new Promise((resolve, reject) =>{
axios.get(api, params).then((tes)=>{resolve(res)})
})
}
export default http
在react組件中使用
const res = await http.post(url, params)