JavaScript中iframe(內嵌框架)在網頁開發中有著廣泛的應用,但是當iframe加載的資源不在同一域(Domain)下,就會遇到跨域問題。例如,Parent頁面包含一個iframe標簽,而iframe標簽的src屬性指向的是外部域的一個網頁,這就呈現了一個跨域的情況。
原因很簡單,跨域訪問會造成安全漏洞。如果一個網站可以隨意訪問另一個域上的資源,這就會導致基于Web的安全漏洞,例如跨站腳本攻擊(Cross-Site Scripting,XSS)等惡意行為。為此,Web瀏覽器中的同源策略(Same-Origin Policy)被設計出來,規定了來自不同源的文檔或腳本不能相互訪問。
解決跨域問題的方法有很多,通常有以下幾種:
一、使用Window.postMessage()方法
// Parent頁面 var otherWindow = document.getElementById('iframe').contentWindow; otherWindow.postMessage('Hello', 'http://child.domain.com'); // iframe頁面 window.addEventListener('message', function(event) { if (event.origin !== 'http://parent.domain.com') return; console.log(event.data); }, false);
二、使用JSONP(JSON with Padding)
// Parent頁面 function handleResponse(response) { console.log(response); } var script = document.createElement('script'); script.src = 'http://child.domain.com/jsonp?callback=handleResponse'; document.body.appendChild(script); // iframe頁面 var data = { name: 'Jack', age: 27 }; var jsonpData = JSON.stringify(data); var jsonp = 'handleResponse(' + jsonpData + ');'; document.write(jsonp);
三、使用代理
// Parent頁面 fetch('/proxy?url=http://child.domain.com') .then(response =>response.text()) .then(text =>console.log(text)); // 服務端 const http = require('http'); const request = require('request'); http.createServer((req, res) =>{ if (req.url.indexOf('/proxy?url=') === 0) { const targetUrl = req.url.substring('/proxy?url='.length); request(targetUrl).pipe(res); } else { res.writeHead(404); res.end(); } }).listen(8000);
不管是哪種方式,都需要經過Web瀏覽器的處理才能完成跨域請求。其中,Window.postMessage()是HTML5推出的跨文檔消息傳遞API,它允許不同的文檔(例如網頁、iframe、popup)之間傳遞簡單的字符串消息,通常用于跨域通信、多窗口或多標簽頁通信等場景。JSONP則是利用了當前Web瀏覽器同源策略的一個漏洞,利用script標簽的src屬性可以跨域請求資源的特性,它將服務器返回的JSON數據包裹在一個回調函數中,然后通過script標簽的src請求到Parent頁面中。代理方式則是在服務端起一個代理服務器,通過代理發起真正的請求。當然,這些方式各有優劣。
下一篇lv 框架php