摘要:為什么會存在跨域問題同源策略由于出于安全考慮,瀏覽器規定不能操作其他域下的頁面,不能接受其他域下的請求不只是,引用非同域下的字體文件,還有引用非同域下的圖片,也被同源策略所約束只要協議域名端口有一者不同,就被視為非同域。
Why
為什么會存在跨域問題
同源策略
由于出于安全考慮,瀏覽器規定JavaScript不能操作其他域下的頁面DOM,不能接受其他域下的xhr請求(不只是js,引用非同域下的字體文件,還有canvas引用非同域下的圖片,也被同源策略所約束)
只要協議、域名、端口有一者不同,就被視為非同域。
如何解決
要解決跨域問題,就要繞過瀏覽器對js的限制,另辟蹊徑
JSONP
這是最簡單,也是最流行的跨域解決方案,它利用script標簽不受同源策略的影響,解決跨域,需要后臺配合,返回特殊格式的數據
前端
后端
// Express(Nodejs) // mock data const USERS=[ {name:"Tom",age:23}, {name:"Jack",age:23} ]; app.get("/user",function (req,res) { let cbName=req.query["callback"]; // 這里做一個容錯處理 res.send(` try{ ${cbName}(${JSON.stringify(USRES)}); }catch(ex) { console.error("The data is invalid"); } `); });
CORS (cross-origin resource sharing)
跨域資源共享,是W3C的一個標準,它允許瀏覽器發送跨域服務器的請求,CORS需要瀏覽器和服務器同時支持
后端
簡單請求和非簡單請求詳情,請閱讀阮一峰老師的博文,這里不再敖述
app.use(function (req,res,next){ res.header("Access-Control-Allow-Origin", "http://localhost:6666"); // 允許跨域的白名單,一般不建議使用 * 號 res.header("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE"); // 允許請求的方法,非簡單請求,會進行預檢 res.header("Access-Control-Allow-Headers", "Content-Type"); // 允許請求攜帶的頭信息,非簡單請求,會進行預檢 res.header("Access-Control-Allow-Credentials","true"); // 允許發送cookie,這里前端xhr也需要一起配置 `xhr.withCredentials=true` next(); });
代理
只要是在與你同域下的服務器,新建一個代理(服務端不存在同源策略),將你的跨域請求全部代理轉發
后端
const proxy=require("http-proxy-middleware"); // 這里使用這個中間件完成代理 app.use("/api", proxy("http://b.com")); // http://a.com/api -> http://b.com/api
window.name+iframe
MDN里解釋道它是獲取/設置窗口的名稱,因為的它在不同頁面甚至域名加載后值都不會改變,該屬性也被用于作為 JSONP 的一個更安全的備選來提供跨域通信(cross-domain messaging)
前端
后端
// Express(Nodejs) // mock data const USERS=[ {name:"Tom",age:23}, {name:"Jack",age:23} ]; app.get("/user",function (req,res) { res.send(` `); });
document.domian
這個使用情況有限,例如
http://a.c.com
http://b.c.com
主域相同時,分別設置他們頁面的document.domain="c.com";
locaction.hash+iframe
嵌套兩層iframe,達到第一層與第三層同域,就可以互相通信了
圖片ping
這個只能發出去請求,無法獲取到服務器的響應,常常用于網站流量統計
let img=new Image(); img.addEventListener("load",function () { console.log("Send success"); // todo }); img.src="http://site.c.com/a.gif?count=666";
postMessage+iframe
postMessage+form+iframe
這個需要后臺配合返回特殊格式的數據,TL,DR 可以看這個demo
WebSocket
WebSocket是一種通信協議,該協議不實行同源政策,
注意需要瀏覽器和服務器都支持的情況下
后端
// Nodejs const server = require("http").createServer(); const io = require("socket.io")(server); io.on("connection", function (client) { client.emit("data", "This message from "http://b.com""); });Summary
目前個人在工作中遇到的解決方法就是這些,當然還有許多其他的方法,你看,其實跨域并不難吧 ^_^
js通過xhr發的跨域請求,雖然得不到響應,但是可以發送出去,其實如果是單向通信的話,也可以,比如文章閱讀統計,網站流量統計
Reference跨域資源共享 CORS 詳解---阮一峰
不要再問我跨域的問題了
FatDong1/cross-domain
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/108787.html
摘要:基本概念首先,函數不能存儲的值,指向哪里,取決于調用它的對象。如果沒有這個對象,那默認就是調用非嚴格模式下。也就是說是在運行的時候定義的,不是在綁定的時候定義的。 基本概念 首先,函數不能存儲this的值,this指向哪里,取決于調用它的對象。如果沒有這個對象,那默認就是window調用(非嚴格模式下)。也就是說this是在運行的時候定義的,不是在綁定的時候定義的。 funct...
摘要:一到底是一門什么樣的計算機編程語言表里不一表面上是動態解釋執行的腳本語言,實際上它是一門編譯語言。與眾不同與傳統語言不同的是,它不是提前編譯的,編譯記過也不能在分布式系統中進行移植。千篇一律引擎進行編譯的步驟和傳統的編譯語言非常相似。 一、JavaScript到底是一門什么樣的計算機編程語言? JavaScript表里不一:表面上是動態、解釋執行的腳本語言,實際上它是一門編譯語言。 ...
摘要:在我們的程序中有很多變量標識符,我們現在或者將來將使用它。當我們使用時,如果并沒有找到這個變量,在非嚴格模式下,程序會默認幫我們在全局創建一個變量。詞法作用域也就是說,變量的作用域就是他聲明的時候的作用域。 作用域 定義 首先我們來想想作用域是用來干什么的。在我們的程序中有很多變量(標識符identifier),我們現在或者將來將使用它。那么多變量,我咋知道我有沒有聲明或者定義過他呢,...
摘要:運行規則根據的運作原理,我們可以看到,的值和調用棧通過哪些函數的調用運行到調用當前函數的過程以及如何被調用有關。 1. this的誕生 假設我們有一個speak函數,通過this的運行機制,當使用不同的方法調用它時,我們可以靈活的輸出不同的name。 var me = {name: me}; function speak() { console.log(this.name); }...
摘要:回調傳遞函數是將函數當做值并作為參數傳遞給函數。這個例子中就是因為事件綁定機制中的傳入了回調函數,產生了閉包,引用著所在的作用域,所以此處的數據無法從內存中釋放。 javascript作用域 一門語言需要一套設計良好的規則來存儲變量,并且之后可以方便的找到這些變量,這逃規則被稱為作用域。 這也意味著當我們訪問一個變量的時候,決定這個變量能否訪問到的依據就是這個作用域。 一、詞法作用域 ...
閱讀 3527·2021-10-08 10:04
閱讀 875·2019-08-30 15:54
閱讀 2190·2019-08-29 16:09
閱讀 1356·2019-08-29 15:41
閱讀 2287·2019-08-29 11:01
閱讀 1746·2019-08-26 13:51
閱讀 1037·2019-08-26 13:25
閱讀 1836·2019-08-26 13:24