js跨域問題總結

一個域名地址的組成

  1. http://(協議)www(子域名).abc.com(主域名):8080(端口號)/somescript/jquery.js(請求資源地址)

爲何會發生ajax跨域

由於瀏覽器同源策略的限制,不容許ajax跨域請求vue

  • 一個是瀏覽器的顯示
  • 另外一個限制的是ajax請求

能夠跨域的三個標籤

  1. <img src='xxx'> :用於打點統計
  2. <link href='xxx'>:可使用CDN資源
  3. <script src='xxx'>:能夠用於JSONP和CDN資源

跨域的解決辦法

針對瀏覽器的限制

open /Applications/Google\ Chrome.app --args --disable-web-security --user-data-dir
複製代碼

jsonp

  1. jsonp是什麼
  2. 使用jsonp服務器後臺須要改動嗎:須要,因此跨域請求都必須通過信息提供方的容許
  3. type
  4. Content-Type

jsonp的弊端

  1. 服務器須要改動代碼支持
  2. 只支持GET請求

服務器端設置http header

response.setHeader('Access-Control-Allow-Origin','http://a.com,http://b.com')
response.setHeader('Access-Control-Allow-Origin','X-Requested-With')
response.setHeader('Access-Control-Allow-Origin','PUT,POST,GET,DELETE,OPTIONS')
// 接收跨域的cookie
response.setHeader('Access-Control-Allow-Credentials','true')
複製代碼

同源策略

同源的目的

  • 網站通常會把一些重要信息放在Cookie或者LocalStorage中,若是沒有同源策略,這些信息能夠共享,若是有人惡意竊取網站數據,這些信息就會被泄露。因此說同源策略是瀏覽器安全的基礎。

同源策略指的是什麼?

  • 同源指的是協議、域名、端口號相同
  • 通常咱們看到的網址沒有顯示端口號,是由於使用的默認端口80,能夠省略

主域名和子域名

跨域帶來問題

  • Cookie、LocalStorage沒法獲取
  • DOM沒法獲取
  • Ajax請求沒法發送

跨域的解決方案

Jsonp跨域

jsonp發送的請求type是script

jsonp返回的數據不是jsonp對象而是js腳本,這個腳本是一個函數的調用,函數的名字是jsonp請求的時候寫的函數,這個jsonp請求返回的值做爲參數。

優勢

  • 兼容性比較好,服務器改造很是小
  • 只能實現get請求,容易遭受XSS攻擊

缺點

  • 服務器端須要改動,返回值再也不是JSON對象,而是JS腳本
  • 只支持GET方法
  • 發送的不是XHR請求

原生JS模擬

function jsonp({url,params,cb}) {            
  return new Promise((resolve, reject) => {                
    let script = document.createElement('script');                
    window[cb] = function (params) {                    
      resolve(params);
    }                
    params = {...params,cb};                
    let arrs = [];       
	for(let key in params){                    
		arrs.push(`${key}=${params[key]}`);                    
	}                
    script.src = `${url}?${arrs.join('&')}`;                
    document.body.appendChild(script);            
  });
};

jsonp({            
   url: 'https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su',            
   params:{wd:'a'},            
   cb:'show'        
}).then(data=>{            
	console.log('jsonp跨域請求的數據爲:',data);        
});
複製代碼

jquery模擬

jquery原代碼也是經過動態建立script標籤的形式實現跨越的jquery

$.ajax({
    url: 'https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su',
    type: 'get',
    data: {wd:'a'},
    dataType: 'jsonp',  // 請求方式爲jsonp
    jsonpCallback: "show",    // 自定義回調函數名
    success:function(){
        
    },
    error:function(){
        
    }
});

複製代碼

vue

this.$http.jsonp('https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su', {
    params: {wd:'a'},
  jsonp: 'show'}).then((res) => {
    console.log(res); 
})
複製代碼

手動編寫一個ajax,不依賴第三方庫

var xhr = new XMLHttpRequest()
xhr.open('GET','/api',false)
xhr.onreadystatechange = function (argument) {
	if(xhr.readyState === 4){
		if(xhr.status === 200){
			alert(xhr.responseTest)
		}
	}
}
xhr.send(null)
複製代碼
相關文章
相關標籤/搜索