深入淺析同源與跨域,jsonp(函數封裝),CORS原理
同源政策
Ajax請求限制:
Ajax 隻能向自己的服務器發送請求
同源策略是瀏覽器的一個安全功能,不同源的客戶端腳本在沒有明確授權的情況下,不能讀寫對方資源。
比如現在有一個A網站、有一個B網站,A網站中的 HTML 文件隻能向A網站服務器中發送 Ajax 請求,
B網站中的 HTML 文件隻向 B 網站中發送 Ajax 請求,但是 A 網站是不能向 B 網站發送 Ajax請求的,
同理,B 網站也不能向 A 網站發送 Ajax請求。
同源:
如果兩個頁面擁有相同的協議、域名和端口,那麼這兩個頁面就屬於同一個源,其中隻要有一個不相同,就是不同源。
http://www.example.com/dir/page.html
http://www.example.com/dir2/other.html:同源http://example.com/dir/other.html:不同源(域名不同)
http://v2.www.example.com/dir/other.html:不同源(域名不同)
http://www.example.com:81/dir/other.html:不同源(端口不同)
https://www.example.com/dir/page.html:不同源(協議不同)
同源政策的目的:
- 同源政策是為瞭保證用戶信息的安全,防止惡意的網站竊取數據。最初的同源政策是指 A 網站在客戶端設置的 Cookie,B網站是不能訪問的。
- 隨著互聯網的發展,同源政策也越來越嚴格,在不同源的情況下,其中有一項規定就是無法向非同源地址發送Ajax 請求,如果請求,瀏覽器就會報錯。
不受同源策略限制:
頁面中的鏈接,重定向以及表單提交是不會受到同源策略限制的跨域資源的引入是可以的。但是js不能讀寫加載的內容。如嵌入到頁面中的<script src="..."></script>
,<img>
,<link>
,<iframe>
等
跨域問題
跨域:隻要協議、域名、端口號有一個不同就是跨域
跨域的原因:
跨域問題 來源於 JavaScript的同源策略,即隻有 協議+主機名+端口號(如存在)相同,則允許相互訪問。
為瞭防止某域名下的接口被其他域名下的網頁非法調用,是瀏覽器對JavaScript施加的安全限制。
也就是說JavaScript隻能訪問和操作自己域下的資源,不能訪問和操作其他域下的資源。
跨域問題是針對 JS 和 Ajax 的, html 本身沒有跨域問題,
比如a標簽、script標簽、甚至form標簽(可以直接跨域發送數據並接收數據) 等
解決跨域問題:
JSONP
:利用script標簽可跨域的特點,在跨域腳本中可以直接回調當前腳本的函數。
CORS
:服務器設置HTTP響應頭中Access-Control-Allow-Origin
值,解除跨域限制。 註意:這兩個跨域方案都存在一個致命的缺陷,嚴重依賴後端的協助。
反向代理(Reverse Proxy
):前端獨立就能解決的跨域方案:
指以 代理服務器 來接受internet上的連接請求,
然後將請求轉發給內部網絡上的服務器,
並將從服務器上得到的結果返回給internet上請求連接的客戶端,
此時代理服務器對外就表現為一個反向代理服務器。
JSONP
使用 JSONP 解決
jsonp 是 JSON with padding(填充式 JSON 或參數式 JSON)的簡寫,它 不屬於 Ajax 請求,但它可以 模擬 Ajax 請求
JSONP 由兩部分組成:回調函數和數據
- 回調函數是當響應到來時應該在頁面中調用的函數。回調函數的名字一般是在請求中指定的。
- 數據就是傳入回調函數中的 JSON 數據。
解決方法:
簡單理解:在服務器端將json數據作為函數參數,填充到函數當中,在客戶端中調用函數從而對數據進行處理
JSONP實現跨域請求的原理簡單的說,就是動態創建<script>
標簽,然後利用<script>
的 src 不受同源策略約束來跨域獲取數據。
JSONP的優缺點:
優點:
不像XMLHttpRequest對象實現的Ajax請求那樣受到同源策略的限制兼容性更好,在更加古老的瀏覽器中都可以運行,
不需要XMLHttpRequest或ActiveX的支持並且在請求完畢後可以通過調用callback的方式回傳結果
缺點:
隻支持GET請求而不支持POST等其它類型的HTTP請求隻支持跨域HTTP請求這種情況,
不能解決不同域的兩個頁面之間如何進行JavaScript調用的問題
JSONP代碼優化:
客戶端需要將函數名稱傳遞到服務器端
將 script 請求的發送變成動態請求
封裝 jsonp 函數,方便請求發送
服務器端代碼優化之res.jsonp 方法
JSONP函數封裝:
function jsonp (options) { // 動態創建script標簽 var script = document.createElement('script'); // 拼接字符串的變量 var params = ''; for (var attr in options.data) { params += '&' + attr + '=' + options.data[attr]; } // myJsonp0124741 var fnName = 'myJsonp' + Math.random().toString().replace('.', ''); // 將它變成全局函數 window[fnName] = options.success; // 為script標簽添加src屬性 script.src = options.url + '?callback=' + fnName + params; // 將script標簽追加到頁面中 document.body.appendChild(script); // 為script標簽添加onload事件 script.onload = function () { document.body.removeChild(script); } }
使用:
// 獲取按鈕 var btn1 = document.getElementById('btn1'); var btn2 = document.getElementById('btn2'); // 為按鈕添加點擊事件 btn1.onclick = function () { jsonp({ // 請求地址 url: 'http://localhost:3001/better', data: { name: 'lisi', age: 30 }, success: function (data) { console.log(123) console.log(data) } }) } btn2.onclick = function () { jsonp({ // 請求地址 url: 'http://localhost:3001/better', success: function (data) { console.log(456789) console.log(data) } }) }
CORS
使用CORS解決
CORS:全稱為 Cross-origin resource sharing,即跨域資源共享,它允許瀏覽器向跨域服務器發送 Ajax 請求,克服瞭 Ajax 隻能同源使用的限制。
//設置服務器的響應頭信息,實現跨域 res.setHeader("Access-Control-Allow-Origin", "*"); /* 星號表示所有的域都可以接受, */
Express框架中跨域的實現:
安裝跨域模塊:語法: npm install cors
在app.js文件中引入cors模塊:var cors = require('cors')
使用跨域模塊(在app.js文件中) :app.use(cors())
以上就是深入淺析同源與跨域,jsonp(函數封裝),CORS原理的詳細內容,更多關於同源與跨域,jsonp(函數封裝),CORS的資料請關註WalkonNet其它相關文章!