理解跨域及常用解決方案

2021-09-13 02:22:49 字數 3868 閱讀 5313

跨域,相信大家無論是在工作中還是在面試中經常遇到這個問題,常常在網上看到別人所整理的一些方法,看似知道是怎麼回事,但如果沒有動手實踐過,總覺得自己沒有真正的掌握,在這裡,通過自己認真思考整理一些常用的方法。
不用多講,作為一名前端開發人員,相信大家都知道跨域是因為瀏覽器的同源策略所導致的。所謂同源是指"協議+網域名稱+埠"三者相同,即便兩個不同的網域名稱指向同乙個ip位址,也非同源。瀏覽器引入同源策略主要是為了防止xss,csrf攻擊。

csrf(cross-site request forgery),跨站請求偽造,也被稱為:one click attack/session riding,縮寫為:csrf/xsrf。
在同源策略影響下,網域名稱a向網域名稱b傳送ajax請求,或操作cookie、localstorage、indexdb等資料,或操作dom,js就會受到限制,但請求css,js等靜態資源不受限制

首先說一下jsonp的原理,例如我們平時寫html的時候常常會使用

這種方式去取放在另外伺服器上的靜態資源,這個是不受同源策略所限制的,所以我們利用這一點可以解決跨域的問題。

主要**如下:

在www.a.com網域名稱寫下如下**,去請求www.b.com網域名稱的資料
這裡,我們利用動態指令碼的src屬性,變相地傳送了乙個這時候,b.com頁面接受到這個請求時,如果沒有jsonp,會正常返回json的資料結果,像這樣:,而利用jsonp,服務端會接受這個callback引數,然後用這個引數值包裝要返回的資料:demo();

這時候,如果a.com的頁面上正好有乙個demo 的函式:

function demo(res)

});以nodejs為例

//引入url模組解析url字串

var url = require('url);

//引入querystring模組處理query字串

跨域資源共享(cors) 是一種機制,它使用額外的 http 頭來告訴瀏覽器 讓執行在乙個 origin (domain) 上的web應用被准許訪問來自不同源伺服器上的指定的資源。當乙個資源從與該資源本身所在的伺服器不同的域或埠請求乙個資源時,資源會發起乙個跨域 http 請求。

cross-origin resource sharing跨域資源共享,應該算是現在比較推薦的跨域處理方案.不僅適用於各種method,而且更加方便和簡單

目前,所有瀏覽器都支援該功能,ie瀏覽器不能低於ie10。

瀏覽器將cors請求分成兩類:簡單請求(****** request)和非簡單請求(not-so-****** request)。

簡單請求同時滿足以下條件,只要不滿足以下條件的則為非簡單請求

非簡單請求會發出一次預檢測請求,返回碼是204,預檢測通過才會真正發出請求,這才返回200。這裡通過前端發請求的時候增加乙個額外的headers來觸發非簡單請求。
對於附帶身份憑證的請求,伺服器不得設定 access-control-allow-origin 的值為「*」。

這是因為請求的首部中攜帶了 cookie 資訊,如果 access-control-allow-origin

的值為「*」,請求將會失敗。而將 access-control-allow-origin 的值設定為

則請求將成功執行。

var express=require('express');

var url=require('url');

var allowcrossdomain = function(req, res, next) ;

var queryvalue=url.parse(req.url).query;

if(queryvalue==='[email protected]')else

});

實際開發過程中,為了安全,會和token一起使用
postmessage是html5 xmlhttprequest level 2中的api,且是為數不多可以跨域操作的window屬性之一,它可用於解決以下方面的問題:

用法:postmessage(data,origin)方法接受兩個引數,

data:需要傳遞的資料,html5規範支援任意基本型別或可複製的物件,但部分瀏覽器只支援字串,所以傳參時最好用json.stringify()序列化。

origin:協議+主機+埠號,也可以設定為"*",表示可以傳遞給任意視窗,如果要指定和當前視窗同源的話設定為"/"。

**示例:

這種方式只適合主網域名稱相同,但子網域名稱不同的iframe跨域。

實現原理:兩個頁面都通過js強制設定document.domain為基礎主域,就實現了同域。

使用方式:

"

window.name 傳輸技術的基本原理:

當在瀏覽器中開啟乙個頁面,或者在頁面中新增乙個iframe時即會建立乙個對應的window物件,當頁面載入另乙個新的頁面時,window.name的屬性是不會變的。這樣就可以利用在頁面動態新增乙個iframe然後載入資料頁面,在資料頁面將需要的資料賦值給window.name。然而此時承載的iframe的parent頁面還是不能直接訪問不在同一域下的iframe的那麼屬性,這時,只需要將iframe再載入乙個與承載頁面同域的空白頁面,即可對window.name進行資料讀取。

通過iframe的src屬性由外域轉向本地域,跨域資料即由iframe的window.name從外域傳遞到本地域。這個就巧妙地繞過了瀏覽器的跨域訪問限制,但同時它又是安全操作。

具體實現:

主頁面資料頁面

**頁面

**:

**:

window.name = '123'
空白

server    

}

配置之後就不需要前端做什麼修改了,一般我們在前後端分離專案中開發階段會採用這種方式,但不是所有場景都能這樣做,例如後端介面是乙個公共的api,比如一些公共服務獲取天氣什麼的。
websoket協議天然支援跨域,你只需要學會如何使用它即可,關於websocket協議請看我的另外一篇文章websocket網路通訊協議

參考文章:

跨域問題及解決方案

閱讀目錄 回到頂部 自 跨域是指我們訪問乙個 如 這個url,從這個頁面中又去訪問這個url,這個時候就引發了跨域,當網域名稱 埠 二級網域名稱不同都會引發跨域。此時9000埠的服務端可以接收到請求,也會給瀏覽器響應資料,但是到達瀏覽器後就被攔截了,因為瀏覽器的同源策略。url結果 原因成功網域名稱...

跨域問題及解決方案

跨域是指我們訪問乙個 如 這個url,從這個頁面中又去訪問這個url,這個時候就引發了跨域,當網域名稱 埠 二級網域名稱不同都會引發跨域。此時9000埠的服務端可以接收到請求,也會給瀏覽器響應資料,但是到達瀏覽器後就被攔截了,因為瀏覽器的同源策略。url結果 原因成功網域名稱 協議 埠相同 失敗協議...

js跨域及解決方案

當前發起請求的域與該請求指向的資源 該請求所在的頁面 所在的域不一樣。此時該請求就會受到瀏覽器sop 同源策略 的限制,這樣做可以降低被csrf 跨站請求偽造 攻擊的可能,但是同源策略並不能避免csrf。對csrf感興趣的可以戳這裡 這裡的域指的是這樣的乙個概念 我們認為若協議 網域名稱 埠號均相同...